一個native crash最后是重寫ViewPager解決的,過程中發現這三個回調還有點繞,於是理了一下
ViewPager有兩個操作,一個是用手指滑動翻頁,一個是直接setCurrentItem(一般用於點擊上面的tab直接setCurrentItem)。下面的方法介紹也會針對這兩種情況分別介紹。
onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
- 這個方法會在屏幕滾動過程中不斷被調用
- 第一個position(這個參數要特別注意一下):位置
- 當用手指滑動時
- 如果手指按在頁面上不動,position和當前頁面index是一致的
- 如果手指向左拖動(相應頁面向右翻動),這時候position大部分時間和當前頁面是一致的,只有翻頁成功的情況下最后一次調用才會變為目標頁面
- 如果手指向右拖動(相應頁面向左翻動),這時候position大部分時間和目標頁面是一致的,只有翻頁不成功的情況下最后一次調用才會變為原頁面
- 當直接設置setCurrentItem翻頁時
- 如果是相鄰的情況(比如現在是第二個頁面,跳到第一或者第三個頁面)
- 如果頁面向右翻動,大部分時間是和當前頁面是一致的,只有最后才變成目標頁面
- 如果向左翻動,position和目標頁面是一致的。這和用手指拖動頁面翻動是基本一致的。
- 如果不是相鄰的情況
- 比如我從第一個頁面跳到第三個頁面,position先是0,然后逐步變成1,然后逐步變成2
- 我從第三個頁面跳到第一個頁面,position先是1,然后逐步變成0,並沒有出現為2的情況
- positionOffset:當前頁面因滑動而偏移了多少比例
- 如果頁面向右翻動,這個值不斷變大,最后在趨近1的情況后突變為0
- 如果頁面向左翻動,這個值不斷變小,最后變為0。
- positionOffsetPixels:當前頁面因滑動而偏移了多少像素
- 變化情況和positionOffset一致
- 一次滑動實例:
onPageSelected(int position)
- 共同
- position是滑動結果,也就是新頁面的的index
- 必須切到一個跟上一個不一樣的頁面才會調用(另兩個不需要)
- 手指滑動
- 用手指滑動翻頁的時候,如果翻動成功了(滑動的距離夠長),手指抬起來一瞬間就會立即執行這個方法,不是在滑動結束的時候回調
- setCurrentItem翻頁
- 這種情況在onPageScrolled執行方法前就會立即執行
onPageScrollStateChanged(int state)
- 共同
- state有三個值:0(END),1(PRESS) , 2(UP)
- 手指滑動
- (滑動時)手指按下去的時候會觸發這個方法,state值為1
- 手指抬起時,如果發生了滑動(即使很小),就會觸發這個方法,這個值會變為2
- 最后滑動結束,頁面停止的時候,也會觸發這個方法,值變為0
- 所以一次手指滑動會執行這個方法三次
- 一種特殊情況是手指按下去以后一點滑動也沒有發生,這個時候只會調用這個方法兩次,state值分別是1,0
- setCurrentItem翻頁
- 會執行這個方法兩次,state值分別為2 , 0
用手指拖動翻頁時,三個方法的執行順序為:
- 最先執行一遍onPageScrollStateChanged(1)
- 然后不斷執行onPageScrolled
- 放手指的時候,直接立即執行一次onPageScrollStateChanged(2)
- 然后立即執行一次onPageSelected
- 然后再不斷執行onPageScrolled
- 最后執行一次onPageScrollStateChanged(0)