一、ViewPager的簡單使用
1.設(shè)置數(shù)據(jù):
具體頁面可以使用adapter來實(shí)現(xiàn),刷新數(shù)據(jù)使用adapter的notifyDataSetChanged,無限滑動可以通過改變adapter的getCount方法和自己的setCurrentItem來實(shí)現(xiàn)。
2.常用基本方法:
ViewPager.setOffscreenPageLimit(3); // viewPager的緩存頁數(shù)
ViewPager.setPageMargin(CommonUtils.dip2px(activity, 15)); // viewPager頁與頁之前的間距
ViewPager.setPageTransformer(false, new AlphaTransformer()); // viewPager 滑動過程中動效的設(shè)置
3.自定義:
通過自定義可以實(shí)現(xiàn)是否可以滑動換頁
是否需要滑動效果
等等
最簡單的指示器代碼如下圖
具體效果:
有多少個頁面就有多少個指示器圖標(biāo),可以是圖片也可以自己通過shape畫,一般都是灰白圓點(diǎn)。
主要通過onPageSelected變化具體點(diǎn)位。
以前用setOnPageChangeListener
現(xiàn)在被addOnPageChangeListener替換

二、OnPageChangeListener
1.onPageSelected(int position):
這個方法有一個參數(shù)position,代表哪個頁面被選中。
當(dāng)用手指滑動翻頁的時候,如果翻動成功了(滑動的距離夠長),手指抬起來就會執(zhí)行這個方法,position就是當(dāng)前滑動到的頁面。
這個方法一般被用來獲取滑動過后當(dāng)前頁。
2.onPageScrolled(int position,float positionOffset, int positionOffsetPixels):
這個方法會在屏幕滾動過程中不斷被調(diào)用。
有三個參數(shù),第一個position
第二個positionOffset是當(dāng)前頁面滑動比例,如果頁面向右翻動,這個值不斷變大,最后在趨近1的情況后突變?yōu)?。如果頁面向左翻動,這個值不斷變小,最后變?yōu)?。
第三個positionOffsetPixels是當(dāng)前頁面滑動像素,變化情況和positionOffset一致。
我理解的position 就是間隔與位置A的關(guān)系,position的值取至位置A同位置或位置A左邊的間隔值,如上圖此時position為1,當(dāng)item左滑過程中,位置A左邊是間隔1,所有返回的值一直是1,若右滑,位置A左邊的就是間隔0,那返回值就是0,當(dāng)左滑停止時,間隔2與位置A重疊,返回值就變成2了,同理右滑停止時就是0。

下圖是setCurrentItem到最后一頁的日志。

3.onPageScrollStateChanged(int state):這個方法在手指操作屏幕的時候發(fā)生變化。有三個值:0(END),1(PRESS) , 2(UP) 。
當(dāng)用手指滑動翻頁時,手指按下去的時候會觸發(fā)這個方法,state值為1,手指抬起時,如果發(fā)生了滑動(即使很?。?,這個值會變?yōu)?,然后最后變?yōu)? ??偣矆?zhí)行這個方法三次。一種特殊情況是手指按下去以后一點(diǎn)滑動也沒有發(fā)生,這個時候只會調(diào)用這個方法兩次,state值分別是1,0 。
當(dāng)setCurrentItem翻頁時,會執(zhí)行這個方法兩次,state值分別為2 , 0 。
舉個’栗子’:以我本次UI為例,onPageScrolled方法處理滑動過程中,小點(diǎn)點(diǎn)大小變化,onPageScrollStateChanged被調(diào)用后,清空onPageScrolled中判斷的舊值,onPageSelected被調(diào)用后設(shè)置顏色變化和頁面具體邏輯。
此方法適合Item外的變化,Item的變化可以用setPageTransformer。
顏色也可以變化,因?yàn)轭伾a是6個16進(jìn)制數(shù),可以通過倆個數(shù)的差值與position計(jì)算。

三、滑動動效
ViewPager.setPageTransformer(false, new AlphaTransformer());
第一個參數(shù)boolean型 item層級方向
通過自定義 Transformer 可以實(shí)現(xiàn)自己想要的動效
下圖是一個跟隨滑動改變透明度的代碼

transformPage
倆個參數(shù) View page ,float position
Page就是Item對應(yīng)的view
Position就是當(dāng)前頁滑動位置
下圖是當(dāng)前位item左滑的全部過程

如果你想只有一頁的動效你只需要找
-1 < Position < 0
這個區(qū)間的item就可以了
如果是多頁的動效,你需要根據(jù)Position 大小去做對應(yīng)的操作


你可以在這個過程中做你任何想做的事,例如:
透明度
setAlpha 百分比
縮放
setPivotX setPivotY 設(shè)置縮放中心點(diǎn)位置像素
setScaleX setScaleY 具體縮放值百分比
位移
setTranslationX setTranslationY 像素
旋轉(zhuǎn)
setPivotX setPivotY 設(shè)置旋轉(zhuǎn)中心點(diǎn)位置像素
setRotationX setRotationY setRotation 繞XYZ旋轉(zhuǎn) 參數(shù)是旋轉(zhuǎn)度數(shù)
如果你想根據(jù)滑動狀態(tài)實(shí)現(xiàn)item內(nèi)部某個控件的動效,可以通過findViewById 可以找到對應(yīng)控件進(jìn)行對應(yīng)動效,你可以為所欲為。
有些動畫或布局可能超過父類你需要下面這個屬性
android:clipChildren 父類屬性 clipChild用來定義他的子控件是否要在他應(yīng)有的邊界內(nèi)進(jìn)行繪制。
一些我寫過的效果



Viewpager缺點(diǎn):
缺點(diǎn):Viewpager adapter 生成itemUI后,用notify方法只能刷新數(shù)據(jù),不會刷新UI,只有當(dāng)UI被銷毀后,重新生成才會生效,還有一種方法getItemPosition能刷新,但是也有缺點(diǎn),就是每次都會重新創(chuàng)建Item。
ViewPager一次只切換一頁
ViewPager層級是固定的只能一個方向復(fù)蓋下去,要么頭層級最高,要么尾層級最高

RecyclerView + SnapHelper實(shí)現(xiàn)類似ViewPager效果
https://www.itdecent.cn/p/ef3a3b8d0a77
RecyclerView 可以切換多頁也可以切換一頁
RecyclerView 實(shí)現(xiàn)后 層級可以實(shí)現(xiàn)中間最高
RecyclerView 如果不自定義,是快速滑動效果
RecyclerView 可以實(shí)現(xiàn)簡單ViewPager效果 和 比ViewPager效果更好的效果,但是如果UI上明顯是ViewPager的效果 想用RecyclerView 完全復(fù)制就不如直接用ViewPager了。
我為什么喜歡自己寫UI效果:
- 很難找到完全一樣效果的開源代碼,找個類似的然后花費(fèi)時間去讀懂別人代碼后再加工時間成本會更高。
- 一般開源代碼,都會給你很多種效果供選擇,代碼量會很大,層級和架構(gòu)會比較復(fù)雜,也不便于你再加工。
- 你沒辦法讓UI設(shè)計(jì)師像你妥協(xié),有時候再加工后才發(fā)現(xiàn)差一丟丟,這一丟丟很難再弄出來,你基本算是白干了。