[关闭]
@TryLoveCatch 2018-10-19T14:57:29.000000Z 字数 3326 阅读 2591

ViewPage动画PageTransformer分析

android ViewPager PageTransformer


简介

PageTransformer是一个允许你修改ViewPager默认滑动动画的接口,当我们在滑动ViewPager中的页面的过程中,会多次调用这个方法,并给我们传递了两个参数View pagefloat position

  1. public interface PageTransformer {
  2. void transformPage(View page, float position);
  3. }

通过它可以实现一些非常炫酷的滑动动画。今天我们来实现视觉差滚动的效果。

所谓视觉差效果,我们可以这样理解,比如 ViewPager 滑动了1px ,而该Page中的TextView移动2pxImageView移动0.5px,这样我们看到就是TextViewImageView移动的快,从而形成了视觉差。
同一个界面中的元素,由于层级不同,赋予不同的速度,在移动速度上的差异形成了视差的错觉,这就是我们要追求的效果

测试

好了,说了这么多,我们先来了解一下PageTransformer这个接口吧。
我自定义了一个PageTransformer,仅仅是打印了两个参数View pagefloat position,如下:

刚进入
page1 , 0.0
page2 , 1.0

这里比较好理解,进入App,默认打开ViewPager的第一个页面,并且 预加载第二个页面,所以会有打印两条,关于后面position的意思,我们下面在说,当然,这个和ViewPagerposition没有任何关系。

1-->2
page1 , -0.0055555557
page2 , 0.99444443
page1 , -0.022222223
page2 , 0.9777778
page1 , -0.03888889
page2 , 0.9611111
page1 , -0.05648148
page2 , 0.9435185
page1 , -0.9990741
page2 , 9.259259E-4
page1 , -1.0
page2 , 0.0

手指向左滑动,从page1page2,通过上面的打印我们可以得出结论:

2-->1
page1 , -0.9990741
page2 , 9.259259E-4
page3 , 1.0009259
page1 , -0.975
page2 , 0.025
page3 , 1.025
page1 , -0.95092595
page2 , 0.049074072
page3 , 1.049074
page1 , -9.259259E-4
page2 , 0.9990741
page3 , 1.9990741
page1 , 0.0
page2 , 1.0
page3 , 2.0

手指向右滑动,从page2page1,通过上面的打印我们可以得出结论:

2-->3
page1 , -1.0222223
page2 , -0.022222223
page3 , 0.9777778
page1 , -1.0694444
page2 , -0.06944445
page3 , 0.9305556
page1 , -1.1222222
page2 , -0.12222222
page3 , 0.87777776
page1 , -1.9990741
page2 , -0.9990741
page3 , 9.259259E-4
page1 , -2.0
page2 , -1.0
page3 , 0.0

测试结论

1、position并不是我们以为的View位置,而是表示一种状态:
== 0代表完全显示;
>= 1代表在屏幕右侧完全不显示;
<=-1代表在屏幕左侧完全不显示。
2、我们其实并不需要关心所有的position,我们只需要关系正在呈现给用户的情况,所以,我们只用处理[-1,1],不用关心[-Infinity,-1)(1,+Infinity]

基本处理

  1. private class MyTransformer implements ViewPager.PageTransformer {
  2. @Override
  3. public void transformPage(View page, float position) {
  4. if (position < -1) { // [-Infinity,-1)
  5. //不需要处理
  6. } else if (position <= 1) { // [-1,1]
  7. //具体动画逻辑
  8. } else { // (1,+Infinity]
  9. //不需要处理
  10. }
  11. }
  12. }

最好写成一个基类,以便于扩展,而且有的时候很[-1, 1]会细分为[-1, 0](0, 1]

  1. public abstract class BasePageTransformer implements ViewPager.PageTransformer {
  2. /**
  3. * Apply a property transformation to the given page.
  4. *
  5. * @param view Apply the transformation to this page
  6. * @param position Position of page relative to the current front-and-center
  7. * position of the pager. 0 is front and center. 1 is one full
  8. */
  9. @Override
  10. public void transformPage(View view, float position) {
  11. if (position < -1.0f) { // [-Infinity,-1) 不可见状态
  12. // This page is way off-screen to the left.
  13. handleInvisiblePage(view, position);
  14. } else if (position <= 0.0f) { // [-1,0] 可见状态,设置动画效果 左边的item
  15. // Use the default slide transition when moving to the left page
  16. handleLeftPage(view, position);
  17. } else if (position <= 1.0f) { // (0,1] 可见状态,设置动画效果 右边的item
  18. handleRightPage(view, position);
  19. } else { // (1,+Infinity] 不可见状态
  20. // This page is way off-screen to the right.
  21. handleInvisiblePage(view, position);
  22. }
  23. }
  24. public abstract void handleInvisiblePage(View view, float position);
  25. public abstract void handleLeftPage(View view, float position);
  26. public abstract void handleRightPage(View view, float position);
  27. }

动画实例

效果如下

代码地址

PageTransformerDemo
PageTransformer

Demo下载

Demo下载

参考:

Android ViewPager切换之PageTransformer接口中transformPage方法position参数使用详解
ViewPager 从入门到带你撸个启动页之实战PageTransformer切换动画特效(四)
用PageTranformer实现更炫酷的动画

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注