您的位置:首页 > 其它

千变万化的ViewPager切换动画(二、自定义切换动画)

2016-02-02 21:17 507 查看
现在,来尝试自定义一个简单的切换动画。不过,该从何处下手呢?当然是依葫芦画咯~上一片博客不是有提到谷歌官方提供的DepthPageTransformer和ZoomOutPageTransformer类吗?在这里,可以先分析一下官方的类,在了解之后,就可以照着自定义了。

这里以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());
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: