ViewPager滑动过程中的指示器与页面动效

一、ViewPager的简单使用
1.设置数据:
具体页面可以使用adapter来实现,刷新数据使用adapter的notifyDataSetChanged,无限滑动可以通过改变adapter的getCount方法和自己的setCurrentItem来实现。
2.常用基本方法:
ViewPager.setOffscreenPageLimit(3); // viewPager的缓存页数
ViewPager.setPageMargin(CommonUtils.dip2px(activity, 15)); // viewPager页与页之前的间距
ViewPager.setPageTransformer(false, new AlphaTransformer()); // viewPager 滑动过程中动效的设置
3.自定义:
通过自定义可以实现是否可以滑动换页
是否需要滑动效果
等等

最简单的指示器代码如下图
具体效果:
有多少个页面就有多少个指示器图标,可以是图片也可以自己通过shape画,一般都是灰白圆点。
主要通过onPageSelected变化具体点位。
以前用setOnPageChangeListener
现在被addOnPageChangeListener替换


image.png

二、OnPageChangeListener
1.onPageSelected(int position):
这个方法有一个参数position,代表哪个页面被选中。
当用手指滑动翻页的时候,如果翻动成功了(滑动的距离够长),手指抬起来就会执行这个方法,position就是当前滑动到的页面。
这个方法一般被用来获取滑动过后当前页。

2.onPageScrolled(int position,float positionOffset, int positionOffsetPixels):
这个方法会在屏幕滚动过程中不断被调用。
有三个参数,第一个position
第二个positionOffset是当前页面滑动比例,如果页面向右翻动,这个值不断变大,最后在趋近1的情况后突变为0。如果页面向左翻动,这个值不断变小,最后变为0。
第三个positionOffsetPixels是当前页面滑动像素,变化情况和positionOffset一致。

我理解的position 就是间隔与位置A的关系,position的值取至位置A同位置或位置A左边的间隔值,如上图此时position为1,当item左滑过程中,位置A左边是间隔1,所有返回的值一直是1,若右滑,位置A左边的就是间隔0,那返回值就是0,当左滑停止时,间隔2与位置A重叠,返回值就变成2了,同理右滑停止时就是0。


image.png

下图是setCurrentItem到最后一页的日志。


image.png

3.onPageScrollStateChanged(int state):这个方法在手指操作屏幕的时候发生变化。有三个值:0(END),1(PRESS) , 2(UP) 。
当用手指滑动翻页时,手指按下去的时候会触发这个方法,state值为1,手指抬起时,如果发生了滑动(即使很小),这个值会变为2,然后最后变为0 。总共执行这个方法三次。一种特殊情况是手指按下去以后一点滑动也没有发生,这个时候只会调用这个方法两次,state值分别是1,0 。
当setCurrentItem翻页时,会执行这个方法两次,state值分别为2 , 0 。

举个’栗子’:以我本次UI为例,onPageScrolled方法处理滑动过程中,小点点大小变化,onPageScrollStateChanged被调用后,清空onPageScrolled中判断的旧值,onPageSelected被调用后设置颜色变化和页面具体逻辑。
此方法适合Item外的变化,Item的变化可以用setPageTransformer。
颜色也可以变化,因为颜色代码是6个16进制数,可以通过俩个数的差值与position计算。


image.png

三、滑动动效
ViewPager.setPageTransformer(false, new AlphaTransformer());
第一个参数boolean型 item层级方向
通过自定义 Transformer 可以实现自己想要的动效
下图是一个跟随滑动改变透明度的代码


image.png

transformPage
俩个参数 View page ,float position
Page就是Item对应的view
Position就是当前页滑动位置
下图是当前位item左滑的全部过程


image.png

如果你想只有一页的动效你只需要找
-1 < Position < 0
这个区间的item就可以了
如果是多页的动效,你需要根据Position 大小去做对应的操作


image.png

image.png

你可以在这个过程中做你任何想做的事,例如:
透明度
setAlpha 百分比
缩放
setPivotX setPivotY 设置缩放中心点位置像素
setScaleX setScaleY 具体缩放值百分比
位移
setTranslationX setTranslationY 像素
旋转
setPivotX setPivotY 设置旋转中心点位置像素
setRotationX setRotationY setRotation 绕XYZ旋转 参数是旋转度数
如果你想根据滑动状态实现item内部某个控件的动效,可以通过findViewById 可以找到对应控件进行对应动效,你可以为所欲为。
有些动画或布局可能超过父类你需要下面这个属性
android:clipChildren 父类属性 clipChild用来定义他的子控件是否要在他应有的边界内进行绘制。

一些我写过的效果


![image.png](https://upload-images.jianshu.io/upload_images/19146639-30afb8f1ee9b715b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
image.png
image.png

Viewpager缺点:
缺点:Viewpager adapter 生成itemUI后,用notify方法只能刷新数据,不会刷新UI,只有当UI被销毁后,重新生成才会生效,还有一种方法getItemPosition能刷新,但是也有缺点,就是每次都会重新创建Item。
ViewPager一次只切换一页
ViewPager层级是固定的只能一个方向复盖下去,要么头层级最高,要么尾层级最高


image.png

RecyclerView + SnapHelper实现类似ViewPager效果

https://www.jianshu.com/p/ef3a3b8d0a77

RecyclerView 可以切换多页也可以切换一页

RecyclerView 实现后 层级可以实现中间最高

RecyclerView 如果不自定义,是快速滑动效果

RecyclerView 可以实现简单ViewPager效果 和 比ViewPager效果更好的效果,但是如果UI上明显是ViewPager的效果 想用RecyclerView 完全复制就不如直接用ViewPager了。

我为什么喜欢自己写UI效果:

  1. 很难找到完全一样效果的开源代码,找个类似的然后花费时间去读懂别人代码后再加工时间成本会更高。
  2. 一般开源代码,都会给你很多种效果供选择,代码量会很大,层级和架构会比较复杂,也不便于你再加工。
  3. 你没办法让UI设计师像你妥协,有时候再加工后才发现差一丢丢,这一丢丢很难再弄出来,你基本算是白干了。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容