千变万化的ViewPager切换动画(二、自定义切换动画)
2016-02-02 21:17
507 查看
现在,来尝试自定义一个简单的切换动画。不过,该从何处下手呢?当然是依葫芦画咯~上一片博客不是有提到谷歌官方提供的DepthPageTransformer和ZoomOutPageTransformer类吗?在这里,可以先分析一下官方的类,在了解之后,就可以照着自定义了。
这里以DepthPageTransformer为例(这里为了兼容Android3.0以下已经做了改动):
可以看到在该类里面只有一个方法,包含两个形参,可以在里面添加一行日志,把两个参数都打印出来,看看其在运行时的规律。
上面就是从第一页(在下面暂且设为A页)转到第二页(在下面暂且设为B页)以及打印出的开始部分和最后部分的两个参数的截图。
从两部分日志的截图可以看出,一直是“944d600”和“2f834e39”两个view在交替,当view为“944d600”的时候,对应的position从-0.033333335一直减小到-1.0,而view为“2f834e39”的时候,对应的position从0.96666664一直减小到0.0。
然后看到代码中if-else语句中,可以看到有四部分语句:
1.
此时表明view是看不见的(也就是B页是透明的)
2.
此时实际操作的就是A页(position: -1.0~0.0),可以看到代码的逻辑符合前面动态图所展示的A页的动画要求,透明度一直没变,每一时刻水平移动距离为0(注意这里是每一时刻相对的,要知道前面的日志一直是两个view交替打印的,也就是说,在从A页转到B页的过程中,A、B两页的动画一直交替呈现的。如果在这里不理解的话,可以慢慢的想想下面第3点所解释的),且X与Y轴也一直保持原样没有缩放。
3.
此时实际操作的是B页(position: 1.0~0.0),可以看到代码的逻辑同样符合前面动态图所展示的B页的动画要求,透明度慢慢的从0到1,在每一时刻展示的时候都向右水平移动了一段距离,且X与Y轴越来越放大。
4.
也就是说从A页到B页已经完成了,A页看不见了(变成透明的了)
当然了,上面所说的A页、B页是相对的,当你从第二页转到第三页的时候,会打印三个view的信息。
好了,分析完了之后,就动手实现下图中所展示的效果吧:
其实也比较简单,if-else语句的第一四部分照抄,只要实现中间两个部分的逻辑即可,(这里实现了兼容Android3.0以下,记得要添加nineoldandroids.jar包):
好了,然后在MainActivity中代替原来的动画效果即可一下即可:
这里以DepthPageTransformer为例(这里为了兼容Android3.0以下已经做了改动):
public class DepthPageTransformer implements ViewPager.PageTransformer { private static final float MIN_SCALE = 0.75f; public void transformPage(View view, float position) { int pageWidth = view.getWidth(); Log.d("测试","view="+view+",position="+position); if (position < -1) { // [-Infinity,-1) // This page is way off-screen to the left. ViewHelper.setAlpha(view, 0); } else if (position <= 0) { // [-1,0], A页position: 0.0~-1 // Use the default slide transition when moving to the left page ViewHelper.setAlpha(view, 1); ViewHelper.setTranslationX(view, 0); ViewHelper.setScaleX(view, 1); ViewHelper.setScaleY(view, 1); } else if (position <= 1) { // (0,1], B页position: 1~0.0 // Fade the page out. ViewHelper.setAlpha(view, 1 - position); // Counteract the default slide transition ViewHelper.setTranslationX(view, pageWidth * -position); // Scale the page down (between MIN_SCALE and 1) float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position)); //scaleFactor: 0.75~1 ViewHelper.setScaleX(view, scaleFactor); ViewHelper.setScaleY(view, scaleFactor); } else { // (1,+Infinity] // This page is way off-screen to the right. ViewHelper.setAlpha(view, 0); } } }
可以看到在该类里面只有一个方法,包含两个形参,可以在里面添加一行日志,把两个参数都打印出来,看看其在运行时的规律。
上面就是从第一页(在下面暂且设为A页)转到第二页(在下面暂且设为B页)以及打印出的开始部分和最后部分的两个参数的截图。
从两部分日志的截图可以看出,一直是“944d600”和“2f834e39”两个view在交替,当view为“944d600”的时候,对应的position从-0.033333335一直减小到-1.0,而view为“2f834e39”的时候,对应的position从0.96666664一直减小到0.0。
然后看到代码中if-else语句中,可以看到有四部分语句:
1.
if (position < -1)//[-Infinity,-1)对应的为
// This page is way off-screen to the left. ViewHelper.setAlpha(view, 0);
此时表明view是看不见的(也就是B页是透明的)
2.
else if (position <= 0)//[-1,0]对应的为
// Use the default slide transition when moving to the left page ViewHelper.setAlpha(view, 1); ViewHelper.setTranslationX(view, 0); ViewHelper.setScaleX(view, 1); ViewHelper.setScaleY(view, 1);
此时实际操作的就是A页(position: -1.0~0.0),可以看到代码的逻辑符合前面动态图所展示的A页的动画要求,透明度一直没变,每一时刻水平移动距离为0(注意这里是每一时刻相对的,要知道前面的日志一直是两个view交替打印的,也就是说,在从A页转到B页的过程中,A、B两页的动画一直交替呈现的。如果在这里不理解的话,可以慢慢的想想下面第3点所解释的),且X与Y轴也一直保持原样没有缩放。
3.
else if (position <= 1)对应的为
// Fade the page out. ViewHelper.setAlpha(view, 1 - position); // Counteract the default slide transition ViewHelper.setTranslationX(view, pageWidth * -position); // Scale the page down (between MIN_SCALE and 1) float scaleFactor = MIN_SCALE+ (1 - MIN_SCALE) * (1 -Math.abs(position)); //scaleFactor: 0.75~1 ViewHelper.setScaleX(view, scaleFactor); ViewHelper.setScaleY(view, scaleFactor);
此时实际操作的是B页(position: 1.0~0.0),可以看到代码的逻辑同样符合前面动态图所展示的B页的动画要求,透明度慢慢的从0到1,在每一时刻展示的时候都向右水平移动了一段距离,且X与Y轴越来越放大。
4.
// (1,+Infinity]对应的为
// This page is way off-screen to the right. ViewHelper.setAlpha(view, 0);
也就是说从A页到B页已经完成了,A页看不见了(变成透明的了)
当然了,上面所说的A页、B页是相对的,当你从第二页转到第三页的时候,会打印三个view的信息。
好了,分析完了之后,就动手实现下图中所展示的效果吧:
其实也比较简单,if-else语句的第一四部分照抄,只要实现中间两个部分的逻辑即可,(这里实现了兼容Android3.0以下,记得要添加nineoldandroids.jar包):
public class RotateDownPageTansformer implements ViewPager.PageTransformer { private static final float MAX_ROTATE=20f; private float mRotate; //A页角度变化 0 ~ -20 //B页角度变化 20 ~ 0 //用Rotation(旋转)实现 @Override public void transformPage(View view, float position) { int pageWidth=view.getWidth(); if (position < -1) { ViewHelper.setRotation(view, 0); } else if (position <= 0) {//A页 mRotate=position*MAX_ROTATE;//0 ~ -20 //设置旋转中心为view的底边的中心位置 ViewHelper.setPivotX(view, pageWidth/2); ViewHelper.setPivotY(view, view.getMeasuredHeight()); /*一般在自定义控件的时候getMeasuredWidth/getMeasuredHeight它的赋值在View的setMeasuredDimension中,所以有时可以在onMeasure方法中看到利用getMeasuredWidth/getMeasuredHeight初始化别的参数。而getWidth/getHeight一直在onLayout完成后才会被赋值。一般情况下,如果都完成了赋值,两者值是相同的。*/ ViewHelper.setRotation(view, mRotate); } else if (position <= 1) {//B页 mRotate=position*MAX_ROTATE;//20 ~ 0 //设置旋转中心为view的底边的中心位置 ViewHelper.setPivotX(view, pageWidth/2); ViewHelper.setPivotY(view, view.getMeasuredHeight()); ViewHelper.setRotation(view, mRotate); } else { ViewHelper.setRotation(view, 0); } } }
好了,然后在MainActivity中代替原来的动画效果即可一下即可:
mViewPager.setPageTransformer(true, new RotateDownPageTansformer());
相关文章推荐
- 街区最短路径问题
- Reactor构架模式
- Maven学习 (四) 使用Nexus搭建Maven私服
- 数据类型
- Qt Charts的简单安装与使用
- Struts2的工作原理
- Wunder Fund Round 2016 D. Hamiltonian Spanning Tree
- Python 安装包,简易方法
- ZOJ1004
- VFL--autolayout
- % 运算符 2
- dmesg时间转换工具
- python教程1安装环境
- 胡伯涛论文阅读手记
- javascript异步过程
- 1017. Queueing at Bank (25)
- [土狗之路]coursera上C语言进阶习题 括号匹配
- HDU 5232 Shaking hands
- 解决QT Creator在Linux下的输入法问题
- KMPlayer