ViewPager.OnPageChangeListener方法的含义

最近在写ViewPager的指示器,不可避免用到这个监听器,也调试了很久,谈谈这几个方法的含义。如有错误,请一定要指正,谢谢!

1.onPageScrolled

官方api:

public abstract void onPageScrolled (int position, float positionOffset, int positionOffsetPixels)
This method will be invoked when the current page is scrolled, either as part of a programmatically initiated smooth scroll or a user initiated touch scroll.
Parameters
position Position index of the first page currently being displayed. Page position+1 will be visible if positionOffset is nonzero.
positionOffset Value from [0, 1) indicating the offset from the page at position.
positionOffsetPixels Value in pixels indicating the offset from position.

当页面滑动时,这个方法将被调用,无论是编程方式启动一个平滑滚动,还是用户手动触摸滑动。
编程的方式,是指ViewPager.setCurrentItem(int item)。
第一个参数,position,代表当前正在显示的第一个页面的索引,如果positionOffset不等于0,那么第position+1个页面将被显示。翻译过来就是这样,但还是有点不太明白,后面再分析。
第二个参数,positionOffset,代表position页面的偏移,取值范围是[0,1)。这是一个偏移百分比。
第三个参数,positionOffsetPixels,和第二个意义差不多,只不过单位是像素,偏移的像素值。
测试:从第0个滑动到第1个,然后在滑到第0个,输出:


分析:页面滑动0->1过程中,position从0->1,且只有最后positionOffset为0时position才为1,positionOffset从0->1,不包括边界0和1,最后的1也就是0了,偏移是1就是页数+1且偏移为0。有点绕,其实可以看做是一进制,满1进1,取值范围是[0,1),包括小数。页面滑动1->0过程中,position始终为0,positionOffset从1->0,不包括边界1。
我们来假设一个场景,当前选中的页面是第i页,分左滑和右滑两种:
- 左滑,从第i页滑向第i+1页,目的页面是i+1。参数变化:position开始一直是i,只有最后一次调用为i+1,positionOffset从0开始递增(不包括0),一直递增到1(不包括1),最后再变为0,倒数第二次调用这个值应该是接近1的数,可能是0.9几,受滑动快慢影响。
- 右滑,从第i页滑向第i-1页,目的页面是i-1。参数变化:position一直为i-1,positionOffset从1开始递减(不包括1),一直递减到0。
总结:不管是向左还是向右滑动,总是涉及到两个页面,i和i+1或者i和i-1,当positionOffset!=0时,position值一直是两者中的最小值,当positionOffset==0时,position值为目的页面的序号;positionOffset的值都是左边页面的偏移。

2.onPageSelected

官方api:

public abstract void onPageSelected (int position)
This method will be invoked when a new page becomes selected. Animation is not necessarily complete.
Parameters
position Position index of the new selected page.

当新页面将被选中时调用,动画不是必需完成的。
注意这里的说话,将被选中时,动画不是必需完成,也就是说可能动画还在继续的时候,这个方法就被调用了。这里是个坑,测试下吧。

可以看到positionOffset为0.6几的时候,onPageSelected就被调用了,可能每次试的结果还不一样,由于没看源码,个人猜测,内部可能根据滑动速度和手指按下松开之间的位移,判断是否滑动到目标位置,如果是true,就调用onPageSelected了,而此时很有可能page的滑动动画还没结束。
总结:当onPageSelected()被调用时,页面切换动画还没结束,还会继续调用onPageScrolled()。

3.onPageScrollStateChanged

官方api:

public abstract void onPageScrollStateChanged (int state)
Called when the scroll state changes. Useful for discovering when the user begins dragging, when the pager is automatically settling to the current page, or when it is fully stopped/idle.
Parameters
state The new scroll state.See Also
CROLL_STATE_IDLE
SCROLL_STATE_DRAGGING
SCROLL_STATE_SETTLING

当滑动状态改变时被调用,有助于发现当用户开始拖拽,当页面自动的安放在当前页面,或当页面完全停止。
有三个取值,看看api:

public static final int SCROLL_STATE_DRAGGING
Indicates that the pager is currently being dragged by the user.
Constant Value: 1 (0x00000001)
public static final int SCROLL_STATE_IDLE
Indicates that the pager is in an idle, settled state. The current page is fully in view and no animation is in progress.
Constant Value: 0 (0x00000000)
public static final int SCROLL_STATE_SETTLING
Indicates that the pager is in the process of settling to a final position.
Constant Value: 2 (0x00000002)

    SCROLL_STATE_DRAGGING表示当前页面正在被用户拖拽。
    SCROLL_STATE_IDLE表示viewpager是空闲停止的状态,当前页面完全展示,且没有动画进行。
    SCROLL_STATE_SETTLING表示viewpager解决了最后一个位置的过程。

测试,当页面从0滑动到1时:

可以看到state值1->2->0,1代表刚开始滑动,2在手指松开之后调用,经过多次测试,如果整个过程手指都不松开,那么就不存在这种情况,这里图就不贴了,可以自己测,0是滑动结束时调用。
总结:1代表刚开始滑动,2代表手指松开,如果整个过程手指不松开,那么不会调用这种情况,0代表滑动结束。

总结

好了,分析完了,也算是个总结吧,英语渣,翻译凑合看吧,还是第一次用md写博客,刚开始有点不熟悉。
如有错误,请一定要指正,谢谢!
2015年12月18日23:59:56

你可能感兴趣的:(android学习)