区分ViewPager中的用户滚动和程序页面更改

Ken*_*ngs 32 android android-viewpager

我有一个android.support.v4.view.ViewPager在我的应用程序中,我想区分以编程方式启动的平滑滚动和用户启动的触摸滚动.

我已经看过了ViewPager.OnPageChangeListener,我相信答案可能就在那里,但我只是不确定如何.

Ken*_*ngs 87

好吧,事实证明我对答案的说法是正确的ViewPager.onPageChangeListener.特别是它在于使用onPageScrollStateChanged(int state).基本上有三个状态,一个页面ViewPager可以在:

  1. 拖动:表示用户当前正在拖动寻呼机.
  2. 空闲:表示寻呼机处于空闲,已建立状态.
  3. 结算:表示寻呼机正处于最终位置.

因此,拖动状态仅在用户物理拖动当前页面时发生.因此,当用户刷过页面时,状态按以下顺序发生:拖动 - >稳定 - >空闲.现在,在onPageSelected(int position)"稳定"和"空闲"状态之间调用该方法.因此,为了确定页面改变是否是由用户滚动引起的,只需要检查先前的状态是"拖动"并且当前状态是"正在进行".然后,您可以保留一个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;
}
Run Code Online (Sandbox Code Playgroud)

ifelse if语句不用那么明确,但我这样做是为了便于说明.


cut*_*iko 5

我已将自己的答案标记为正确并在下面的评论中。

首先我分析完整监听器的行为:

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  
Run Code Online (Sandbox Code Playgroud)

发现:

  • 正如您在这两种情况下所看到的,事件在onPageScrollStateChanged移动到时结束SCROLL_STATE_IDLE这意味着 idle 是循环的结束

  • 用户事件是SCROLL_STATE_DRAGGING,然后SCROLL_STATE_SETTLING 是 2states不同于state程序化事件的只有 1 SCROLL_STATE_SETTLING

  • onPageSelected发生在循环结束之前,但在我们能够确定更改是由用户触发还是以编程方式触发之后,因此之前发生的任何事情都会告诉我们此时是否是用户

解决方案:

因此,我使用List<Integer>每次循环结束时都会重置的a ,并且为了能够知道用户是否在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);
}
Run Code Online (Sandbox Code Playgroud)

现在,这个类可以方便地被另一个需要它的人继承。