自定义PageTransformer实现个性切换动画
- public interface PageTransformer {
- /**
- * Apply a property transformation to the given page.
- *
- * @param page Apply the transformation to this page
- * @param position Position of page relative to the current front-and-center
- * position of the pager. 0 is front and center. 1 is one full
- * page position to the right, and -1 is one page position to the left.
- */
- public void transformPage(View page, float position);
- }
可以看到该接口只有一个方法,第一个是我们的view,第二个是position~~
当我们滑动时:会打印出当然ViewPager中存活的每个View以及它们的position的变化~~注意是每一个,所以建议别只log position,不然你会觉得莫名其妙的输出~~
position的可能性的值有,其实从官方示例的注释就能看出:
[-Infinity,-1) 已经看不到了
(1,+Infinity] 已经看不到了
[-1,1]
重点看[-1,1]这个区间 , 其他两个的View都已经看不到了~~
假设现在ViewPager在A页现在滑出B页,则:
A页的position变化就是( 0, -1]
B页的position变化就是[ 1 , 0 ]
知道了我们滑动时position的变化~~那么就开始设计我们的个性的切换效果;
官方给的例子,有变化透明度、偏移量、缩放的,我们准备来个不一样的,我们变化角度,即rotation;
大概的效果是这样的:
下面我们分析代码:
我们设置View的旋转中心为:
ViewHelper.setPivotX(view, view.getMeasuredWidth() * 0.5f);
ViewHelper.setPivotY(view, view.getMeasuredHeight());
依然是ViewPager在A页现在滑出B页
那么A页应当在滑动过程中0度到-20度的偏移,B页应当在滑动过程中+20度到0度的偏移
结合
A页的position变化就是( 0, -1]
B页的position变化就是[ 1 , 0 ]
那么旋转的角度即:mRot = (20 * position); A页 mRot :0 ,~ -20 ; B页 mRot :20 ~ 0 ;
瞬间觉得好简单:
完整代码:
- package com.zhy.view;
- import com.nineoldandroids.view.ViewHelper;
- import android.annotation.SuppressLint;
- import android.support.v4.view.ViewPager;
- import android.util.Log;
- import android.view.View;
- public class RotateDownPageTransformer implements ViewPager.PageTransformer
- {
- private static final float ROT_MAX = 20.0f;
- private float mRot;
- public void transformPage(View view, float position)
- {
- Log.e("TAG", view + " , " + position + "");
- if (position < -1)
- { // [-Infinity,-1)
- // This page is way off-screen to the left.
- ViewHelper.setRotation(view, 0);
- } else if (position <= 1) // a页滑动至b页 ; a页从 0.0 ~ -1 ;b页从1 ~ 0.0
- { // [-1,1]
- // Modify the default slide transition to shrink the page as well
- if (position < 0)
- {
- mRot = (ROT_MAX * position);
- ViewHelper.setPivotX(view, view.getMeasuredWidth() * 0.5f);
- ViewHelper.setPivotY(view, view.getMeasuredHeight());
- ViewHelper.setRotation(view, mRot);
- } else
- {
- mRot = (ROT_MAX * position);
- ViewHelper.setPivotX(view, view.getMeasuredWidth() * 0.5f);
- ViewHelper.setPivotY(view, view.getMeasuredHeight());
- ViewHelper.setRotation(view, mRot);
- }
- // Scale the page down (between MIN_SCALE and 1)
- // Fade the page relative to its size.
- } else
- { // (1,+Infinity]
- // This page is way off-screen to the right.
- ViewHelper.setRotation(view, 0);
- }
- }
- }
你没看错,if else 里面代码是一样的,为了好理解特意没有合并到一起~~~
到此,我们从setPageTransformer使用,到修改ViewPager做到向下兼容,直至自己定义出个性的切换效果 都已经介绍完毕~~
大家可以发挥自己的创造力,做出各种神奇的动画效果,ok,就到这里!
如果你喜欢自定义ViewPager来实现,请移步:Android 自定义 ViewPager 打造千变万化的图片切换效果
滑动屏幕动画
这个就是Viewpager的效果,在上下也滑动之间有一个动画效果,平时使用viewpager是一般不设置,实际上也可以通过实现自己的ViewPager.PageTransformer 来做出完全不同的切换动画效果。官方给出的缩放效果和深度效果的ViewPager.PageTransformer与默认的效果很不同。
自己实现动画关键是理解transformPage(View page, float position)的参数并实现他。page当然值得就是滑动中德那个view,position这里是float,不是平时理解的int位置信息,而是当前滑动状态的一个表示,比如当滑动到正全屏时,position是0,而向左滑动,使得右边刚好有一部被进入屏幕时,position是1,如果前一夜和下一页基本各在屏幕占一半时,前一页的position是-0.5,后一页的posiotn是0.5,所以根据position的值我们就可以自行设置需要的alpha,x/y信息。
Zoom-out page transformer
public class ZoomOutPageTransformer implements ViewPager.PageTransformer { private static float MIN_SCALE = 0.85f; private static float MIN_ALPHA = 0.5f; public void transformPage(View view, float position) { int pageWidth = view.getWidth(); int pageHeight = view.getHeight(); if (position < -1) { // [-Infinity,-1) // This page is way off-screen to the left. view.setAlpha(0); } else if (position <= 1) { // [-1,1] // Modify the default slide transition to shrink the page as well float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position)); float vertMargin = pageHeight * (1 - scaleFactor) / 2; float horzMargin = pageWidth * (1 - scaleFactor) / 2; if (position < 0) { view.setTranslationX(horzMargin - vertMargin / 2); } else { view.setTranslationX(-horzMargin + vertMargin / 2); } // Scale the page down (between MIN_SCALE and 1) view.setScaleX(scaleFactor); view.setScaleY(scaleFactor); // Fade the page relative to its size. view.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA)); } else { // (1,+Infinity] // This page is way off-screen to the right. view.setAlpha(0); } } }
Depth page transformer
public class DepthPageTransformer implements ViewPager.PageTransformer { private static float MIN_SCALE = 0.75f; public void transformPage(View view, float position) { int pageWidth = view.getWidth(); if (position < -1) { // [-Infinity,-1) // This page is way off-screen to the left. view.setAlpha(0); } else if (position <= 0) { // [-1,0] // Use the default slide transition when moving to the left page view.setAlpha(1); view.setTranslationX(0); view.setScaleX(1); view.setScaleY(1); } else if (position <= 1) { // (0,1] // Fade the page out. view.setAlpha(1 - position); // Counteract the default slide transition view.setTranslationX(pageWidth * -position); // Scale the page down (between MIN_SCALE and 1) float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position)); view.setScaleX(scaleFactor); view.setScaleY(scaleFactor); } else { // (1,+Infinity] // This page is way off-screen to the right. view.setAlpha(0); } } }