ViewPager的OnPageChangeListener滑动事件分析

使用代码如下:
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
	@Override
	public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
	}
	@Override
	public void onPageSelected(int position) {
	}
	@Override
	public void onPageScrollStateChanged(int state) {
	}
});

下面是方法介绍:


(1):onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
这个 方法会在加载ViewPager 时调用一次,同时不断滑动 ViewPage r的时候会不停地调用,方法参数如下:
  • position :这个参数有点复杂
    • 如果从 第0个页面 滑到 第1个页面,那么这 position 是0,即当前页面
    • (注意)如果从 第1个页面 滑到 第0个页面,那么这个 position 就是0,即上一个页面;为什么这样设置?下面在分析
  • positionOffset:当前页面偏移的百分比(向右滑动:范围0~1;向左滑动:范围1~0;)
  • positionOffsetPixels:当前页面偏移的像素位置(向右滑动:范围0~1080;向左滑动:范围1080~0; 具体范围因手机不一样,我的手机是1080像素,有的手机可能会是720像素)

加载ViewPager时调用了 onPageScrolled :
 
(2):onPageScrollStateChanged(int state)
这个方法会在 ViewPager 的状态改变的时候调用,方法参数如下:
  • SCROLL_STATE_DRAGGING(值为 1):表示用户手指 按在屏幕上并且开始拖动 的状态(手指按下但是还没有拖动的话,就不会调用这个方法,也不会有这个状态)
  • SCROLL_STATE_IDLE(值为 0):滑动动画做完的状态,也就是不存在余速的状态,这个是滑动 ViewPager 后 ViewPager禁止后的最终状态
  • SCROLL_STATE_SETTLING(值为 2):手指离开屏幕的状态,就是滑动过程中离开了屏幕的状态,这个时候一般会存在余速,所以会切换到 SCROLL_STATE_IDLE 状态

PS:
一般滑动 ViewPager 的状态切换过程
SCROLL_STATE_DRAGGING(值为 1)  -->    SCROLL_STATE_IDLE (值为  0)  -->   SCROLL_STATE_SETTLING (值为  2)

(3):onPageSelected(int position)
当 ViewPager 滑动后定格在 新的 ViewPager后会调用这个方法(这个时候虽然定格了,但是还是会存在余速的,下面演示分析会讲到),方法参数如下:
  • position:新 ViewPager 的位置


具体演示分析:

一、从第0个 ViewPager 滑动到 第1个 ViewPager 
从第0个 ViewPager 滑动到 第1个 ViewPager (有余速:即向右滑动后,手指离开屏幕,ViewPager还会顺着滑动的方向滑动)(一般滑动过程都是有余速的,即使很小心也是存在余速的)

打印代码如下:
    E/MainActivity: onPageScrollStateChanged: state=1
    E/MainActivity: onPageScrolled: position=0 ||||| positionOffset=0.018518519 ||||| positionOffsetPixels=20
    ............
    E/MainActivity: onPageScrolled: position=0 ||||| positionOffset=0.5648148 ||||| positionOffsetPixels=610
    E/MainActivity: onPageScrollStateChanged: state=2
    E/MainActivity: onPageSelected: position=1
    E/MainActivity: onPageScrolled: position=0 ||||| positionOffset=0.64444447 ||||| positionOffsetPixels=696
    ............
    E/MainActivity: onPageScrolled: position=0 ||||| positionOffset=0.9990741 ||||| positionOffsetPixels=1079
    E/MainActivity: onPageScrolled: position=1 ||||| positionOffset=0.0 ||||| positionOffsetPixels=0
    E/MainActivity: onPageScrollStateChanged: state=0


分析:
  • 第 1 行:当手指按在屏幕并开始滑动(切换状态 1),就会调用 onPageScrollStateChanged 方法告诉调用者
  • 第 2 行 到 第 4 行:当手指向右滑动后,就会调用 onPageScrolled 方法
  •  第 5 行:当手指离开屏幕后(切换状态 2),就会 调用 onPageScrollStateChanged  方法告诉调用者
  • 第 6 行:这个时候如果滑动的 ViewPager 能滑动到 第1个 ViewPager ,那么就会调用 onPageSelected 方法告诉调用者能滑到第1个ViewPager
  • 第 7 行  第 9 行:此时还存在余速,并且还没有真正滑到第1个ViewPager,于是会继续调用 onPageScrolled 方法
  • 第 10 行:然后,onPageScrolled 方法会告诉调用者,已经滑到 第1个ViewPager 了
  • 第 11 行:最后,滑动动画做完状态(切换状态 0),调用 onPageScrollStateChanged 方法告诉调用者

总结:
  1. 手指向左滑动时,positionOffset的值 和 positionOffsetPixels 不断变大,当滑动到 新的ViewPager 的时候,这两个值变为0;
  2. 如果能滑动到 新的ViewPager 就会调用 onPageSelected 方法,不然不会调用,可以看一下下面没有滑到 新的ViewPager 的失败演示
  3. 一个能滑动到 新的ViewPager 的过程必定会经历三个状态(1 --> 2 -->0)

滑动失败例子:
    onPageScrollStateChanged: state=1
    onPageScrolled: position=0 ||||| positionOffset=0.014814815 ||||| positionOffsetPixels=16
    onPageScrolled: position=0 ||||| positionOffset=0.039814815 ||||| positionOffsetPixels=43
    ...........
    onPageScrolled: position=0 ||||| positionOffset=0.12962963 ||||| positionOffsetPixels=140
    onPageScrollStateChanged: state=2
    onPageScrolled: position=0 ||||| positionOffset=0.117592596 ||||| positionOffsetPixels=127
    onPageScrolled: position=0 ||||| positionOffset=0.09907407 ||||| positionOffsetPixels=107
    onPageScrolled: position=0 ||||| positionOffset=0.074074075 ||||| positionOffsetPixels=80
    ...........
    onPageScrolled: position=0 ||||| positionOffset=0.0027777778 ||||| positionOffsetPixels=3
    onPageScrolled: position=0 ||||| positionOffset=0.0018518518 ||||| positionOffsetPixels=2
    onPageScrolled: position=0 ||||| positionOffset=9.259259E-4 ||||| positionOffsetPixels=1
    onPageScrolled: position=0 ||||| positionOffset=0.0 ||||| positionOffsetPixels=0
    onPageScrollStateChanged: state=0


PS:如果滑动失败, positionOffset 会等于一个很小很小的值: 9.259259E-4


二、从第1个 ViewPager 滑动到 第0个 ViewPager 
从第1个 ViewPager 滑动到 第0个 ViewPager,重点关注  onPageScrolled 方法中 position 的值的变化

打印代码如下:
    E/MainActivity: onPageScrollStateChanged: state=1
    E/MainActivity: onPageScrolled: position=0 ||||| positionOffset=0.9703704 ||||| positionOffsetPixels=1077
    E/MainActivity: onPageScrolled: position=0 ||||| positionOffset=0.8759259 ||||| positionOffsetPixels=946
    ......
    E/MainActivity: onPageScrolled: position=0 ||||| positionOffset=0.73703706 ||||| positionOffsetPixels=796
    E/MainActivity: onPageScrollStateChanged: state=2
    E/MainActivity: onPageSelected: position=0
    E/MainActivity: onPageScrolled: position=0 ||||| positionOffset=0.27962962 ||||| positionOffsetPixels=302
    .....
    E/MainActivity: onPageScrolled: position=0 ||||| positionOffset=0.0027777778 ||||| positionOffsetPixels=3
    E/MainActivity: onPageScrolled: position=0 ||||| positionOffset=0.0 ||||| positionOffsetPixels=0
    E/MainActivity: onPageScrollStateChanged: state=0



分析:
  • 第 1 行:当手指按在屏幕并开始滑动(切换状态 1),就会调用 onPageScrollStateChanged 方法告诉调用者
  • 第 2 行 到 第 5 行:当手指向左滑动后,就会调用 onPageScrolled 方法,注意!!!这里的 position 是 0 而不是 1,也就是说手指向左滑动,即使是滑动一点点距离的时候,position的值也是 0
  •  第 6 行:当手指离开屏幕后(切换状态 2),就会 调用 onPageScrollStateChanged  方法告诉调用者
  • 第 7 行:这个时候如果滑动的 ViewPager 能滑动到 第 0 个 ViewPager ,那么就会调用 onPageSelected 方法告诉调用者能滑到第 0 个ViewPager
  • 第 8 行  第 10 行:此时还存在余速,并且还没有真正滑到第 0 个ViewPager,于是会继续调用 onPageScrolled 方法
  • 第 10 行:然后,onPageScrolled 方法会告诉调用者,已经滑到 第0个ViewPager 了
  • 第 11 行:最后,滑动动画做完状态(切换状态 0),调用 onPageScrollStateChanged 方法告诉调用者







猜你喜欢

转载自blog.csdn.net/myTempest/article/details/78875104
今日推荐