我的应用程序中有一个android.support.v4.view.ViewPager
,我想区分以编程方式启动的平滑滚动和用户启动的触摸滚动。
我看过了ViewPager.OnPageChangeListener
,我相信答案可能就在那里,但我只是不确定如何。
我的应用程序中有一个android.support.v4.view.ViewPager
,我想区分以编程方式启动的平滑滚动和用户启动的触摸滚动。
我看过了ViewPager.OnPageChangeListener
,我相信答案可能就在那里,但我只是不确定如何。
好的,所以事实证明我对答案的看法是正确的ViewPager.onPageChangeListener
。特别是它在于使用onPageScrollStateChanged(int state)
. ViewPager
本质上,a 中的页面可以处于三种状态:
所以拖动状态只发生在当前页面被用户物理拖动时。因此,当用户滑动页面时,状态按以下顺序发生:拖动 -> 稳定 -> 空闲。现在,该onPageSelected(int position)
方法在“Settling”和“Idle”状态之间被调用。因此,为了确定页面更改是否是由用户滚动引起的,只需要检查之前的状态是“拖动”并且当前状态是“稳定”。然后,您可以保留一个boolean
变量来跟踪页面更改是否是用户发起的,并在您的onPageSelected(int position)
方法中检查它。
这是我的onPageScrollStateChanged
方法
public void onPageScrollStateChanged(int state)
{
if (previousState == ViewPager.SCROLL_STATE_DRAGGING
&& state == ViewPager.SCROLL_STATE_SETTLING)
userScrollChange = true;
else if (previousState == ViewPager.SCROLL_STATE_SETTLING
&& state == ViewPager.SCROLL_STATE_IDLE)
userScrollChange = false;
previousState = state;
}
if
andelse if
语句不需要那么明确,但我这样做是为了清楚起见。
我将自己的答案标记为正确并在下面的评论中。
首先我分析一下完整的监听器是如何表现的:
USER
onPageScrollStateChanged: 1 SCROLL_STATE_DRAGGING
onPageScrollStateChanged: 2 SCROLL_STATE_SETTLING
onPageSelected: SELECTION
onPageScrollStateChanged: 0 SCROLL_STATE_IDLE
PROGRAMATIC
onPageScrollStateChanged: 2 SCROLL_STATE_SETTLING
onPageSelected: SELECTION
onPageScrollStateChanged: 0 SCROLL_STATE_IDLE
正如您在这两种情况下看到的,当onPageScrollStateChanged
移动到时事件结束SCROLL_STATE_IDLE
,这意味着空闲是循环的结束
用户事件是SCROLL_STATE_DRAGGING
,然后SCROLL_STATE_SETTLING
是 2,而states
不是只有 1state
用于程序化事件 SCROLL_STATE_SETTLING
onPageSelected
发生在周期结束之前,但在我们能够确定更改是由用户触发还是以编程方式触发之后,所以之前发生的任何事情都会在那时告诉我们它是否是用户
所以我使用List<Integer>
每次循环结束时重置的,并且能够知道用户是否在onPageSelected
方法中触发了事件,我检查了List
. 如果大小为 2,则表示用户滚动寻呼机。
abstract class PagerListenerActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener {
private static final int USER_SCROLL = 2;
private List<Integer> validator = new ArrayList<>();
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if (validator.size() == USER_SCROLL) {
userScroll(position);
}
}
@Override
public void onPageScrollStateChanged(int state) {
validator.add(state);
if (ViewPager.SCROLL_STATE_IDLE == state) {
validator.clear();
}
}
protected abstract void userScroll(int position);
}
现在,这个类可以方便地被另一个需要它的人继承。
你是对的使用ViewPager.OnPageChangeListener
:
@Override
public void onPageSelected(int arg0) {
// programmatically-initiated
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
// user-initiated touch scroll
}
或者,您可以使用布尔标志来区分programmatically-initiated smooth scroll and a user-initiated touch scroll
. 例如,如果您使用setCurrentItem(int item)
以编程方式更改页面,请尝试:
boolean progChange = false;
....
....
....
progChange = true;
setCurrentItem(somePageId); // Set progChange = true every time
....
....
....
在你的内部ViewPager.OnPageChangeListener
:
@Override
public void onPageSelected(int arg0) {
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
if (progChange) {
// programmatically-initiated
} else {
// user-initiated touch scroll
}
// Set progChange to false;
progChange = false;
}
@Override
public void onPageScrollStateChanged(int arg0) {
}