PageTransformer
ViewPager的默认切换视图的动画是平移方式,如果希望能改变默认的动画效果,增加淡入淡出,缩小放大等效果时,可以实现ViewPager.PageTransformer接口,并将它设置给ViewPager。
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.
*/
void transformPage(View page, float position);
}
PageTransformer接口中只有一个transformPage()方法,包含了两个参数,一个是ViewPager中的可见视图以及相邻2个视图,position代表了相对于屏幕中心的距离。在ViewPager的页面切换过程中,中间的可见页面和该页面的左右相邻两个页面都会触发调用该方法。例如,如果页面3是可见的,当用户拖拽到页面4时,那么在这个拖拽手势的每一步中,页面2,页面3和页面4都会调用transformPage方法。
下面介绍一下position参数的坐标值变化:
例如默认页面为页面2,左边的为页面1,右边的为页面3。页面2此时处于唯一的可见页面,以屏幕的正中心为相对坐标0,页面2的正中心与屏幕正中心的相对距离为0,所以此时position为0。页面1的正中心与屏幕正中心的相对距离为-1,处于不可见状态;页面3的正中心与屏幕正中心的相对距离为1,处于不可见状态。
当从页面2向右拖拽到页面3的过程中,页面1的正中心与屏幕正中心的相对距离小于-1,即[-Infinity,-1),处于不可见状态;页面2的正中心与屏幕正中心的相对距离大于等于-1,小于0,即[-1,0),当向左移动时,position从0到-1变化,处于可见状态;页面3的正中心与屏幕正中心的相对距离大于等于0,小于1,即[0,1),当向左移动时,position从1到0变化,处于可见状态。如下图所示:
即可以将position分4个部分来处理3个页面的变化:
- [-Infinity,-1) 不可见
- [-1,0) 可见,2个页面来回移动左边页面变化值
- [0,1] 可见,2个页面来回移动右边页面变化值
- (1,+Infinity] 不可见
-
transformPage的第一个参数是相对于处于不同position的View,可以根据屏幕上的页面位置,使用View的setAlpha(),setTranslationX(),setScaleY()等方法来设置页面属性来创建自定义的切换动画。
- setAlpha(float alpha)设置透明度
- setTranslationX(float translationX) X轴上平移
- setTranslationY(float translationY) Y轴上平移
- setTranslationZ(float translationZ) Z轴上平移
- setScaleX(float scaleX) X轴上缩放
- setScaleY(float scaleY) Y轴上缩放
- setRotation(float rotation) 原点旋转
- setRotationX(float rotationX) X轴旋转
- setRotationY(float rotationY) Y轴旋转
-
DepthPageTransformer
深度变化动画效果,类似卡片折叠,注意的是ViewPager默认的动画效果是向左和向右平移,无法取消这个动画的,如果想要使页面滑动时保持不动,则必须使用setTranslationX X轴平移动画来与默认的平移动画做相反的变化来抵消默认的平移效果,如下所示:
view.setTranslationX(-1 * view.getWidth() * position);
public class DepthPageTransformer implements ViewPager.PageTransformer { private static final float MIN_SCALE=0.75f; @Override public void transformPage(View page, float position) { int pageWidth=page.getWidth(); if(position<-1){ page.setAlpha(0); }else if(position<=0){//左页面时使用默认的幻灯片转换 page.setAlpha(1); page.setTranslationX(0); page.setScaleX(1); page.setScaleY(1); }else if(position<=1){//右页面 page.setAlpha(1 - position); page.setTranslationX(pageWidth*-position);//抵消默认的幻灯片转换 float scaleFactor=Math.max(MIN_SCALE,1-position); page.setScaleX(scaleFactor); page.setScaleY(scaleFactor); }else{ page.setAlpha(0); } } }
ZoomOutPageTransformer
淡出淡出+缩放的动画效果:
public class ZoomOutPageTransformer implements ViewPager.PageTransformer { private static final float MIN_SCALE=0.85f; private static final float MIN_ALPHA=0.6f; @Override public void transformPage(View page, float position) { int pageWidth=page.getWidth(); int pageHeight=page.getHeight(); if(position<-1){ page.setAlpha(0); }else if(position<=1){ 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){ page.setTranslationX(horzMargin-vertMargin/2); }else{ page.setTranslationX(-horzMargin+vertMargin/2); } page.setScaleX(scaleFactor); page.setScaleY(scaleFactor); page.setAlpha(Math.max(MIN_ALPHA,1-Math.abs(position))); }else{ page.setAlpha(0); } } }
FlyUpPageTransformer
向上向下切换效果:
public class FlyUpPageTransformer implements ViewPager.PageTransformer { private static final float MIN_ALPHA=0.6f; @Override public void transformPage(View page, float position) { int pageWidth=page.getWidth(); int pageHeight=page.getHeight(); if(position<-1){ page.setAlpha(0); }else if(position<=1){ page.setAlpha(Math.max(MIN_ALPHA,1-Math.abs(position))); page.setTranslationX(pageWidth*-position); page.setTranslationY(position*pageHeight); }else{ page.setAlpha(0); } } }
使用方法
使用方法很简单,只需要创建ViewPager实例,然后调用setPageTransformer设置切换动画就可以了:
viewPager.setAdapter(adapter); viewPager.setPageTransformer(true,new FlyUpPageTransformer());