转载请注明出处:http://blog.csdn.net/u013384823/article/details/39187709
做Android开发有一年多了,以前一直用云笔记;现在觉得该学会分享了,并坚持下去!
废话不多说,直接进入正题:
上面是微信的主页切换效果图,随着手指的滑动,两个View的透明度会改变;下面笔者就抛砖引玉,介绍这种效果的实现。
接下来我们看下如何实现这种效果:
1.PageTransformer的介绍:
可参见:http://developer.android.com/training/animation/screen-slide.html#pagetransformer
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);
}
通过ViewPager的setPageTransformer方法来设置切换的具体动画实现,动画的自定义在PageTransformer的抽象方法transformPage(View view,float position)中;
当position<0时,形参中的View是滑动中左边的View;
2.设置ViewPager的动画效果:
demo中的设置动画代码片如下:
mViewPager = (ViewPager) findViewById(R.id.mViewPager);
mViewPager.setAdapter(myAdapter);
// 设置切换的动画
mViewPager.setPageTransformer(true, new PageTransformer() {
private final float MIN_ALPHA = 0.75f;
@Override
public void transformPage(View view, float position) {
if (position < -1) {
view.setAlpha(0);
} else if (position <= 0) {
// 右边的View
view.setAlpha(Math.min(MIN_ALPHA, 1 + position));
} else if (position <= 1) {
// 左边的View
view.setAlpha(Math.min(MIN_ALPHA, 1 - position));
} else {
view.setAlpha(0);
}
}
});
不仅仅可以通过setAlpah,还能通过setTranslationX、setTranslationY、setScaleX、setScaleY等方法搭配组合动画。
3.效果图如下:
4.深入分析:
下面列出ViewPager引用transformPage方法的代码片,很容易的看出,这个方法是如何提供的:
protected void onPageScrolled(int position, float offset, int offsetPixels) {
// Offset any decor views if needed - keep them on-screen at all times.
if (mDecorChildCount > 0) {
final int scrollX = getScrollX();
int paddingLeft = getPaddingLeft();
int paddingRight = getPaddingRight();
final int width = getWidth();
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (!lp.isDecor) continue;
final int hgrav = lp.gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
int childLeft = 0;
switch (hgrav) {
default:
childLeft = paddingLeft;
break;
case Gravity.LEFT:
childLeft = paddingLeft;
paddingLeft += child.getWidth();
break;
case Gravity.CENTER_HORIZONTAL:
childLeft = Math.max((width - child.getMeasuredWidth()) / 2,
paddingLeft);
break;
case Gravity.RIGHT:
childLeft = width - paddingRight - child.getMeasuredWidth();
paddingRight += child.getMeasuredWidth();
break;
}
childLeft += scrollX;
final int childOffset = childLeft - child.getLeft();
if (childOffset != 0) {
child.offsetLeftAndRight(childOffset);
}
}
}
if (mOnPageChangeListener != null) {
mOnPageChangeListener.onPageScrolled(position, offset, offsetPixels);
}
if (mInternalPageChangeListener != null) {
mInternalPageChangeListener.onPageScrolled(position, offset, offsetPixels);
}
if (mPageTransformer != null) {
final int scrollX = getScrollX();
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (lp.isDecor) continue;
final float transformPos = (float) (child.getLeft() - scrollX) / getClientWidth();
mPageTransformer.transformPage(child, transformPos);
}
}
mCalledSuper = true;
}
从加粗的代码来看,ViewPager是在onPageScrolled方法中提供transformPage的实参的,也就是说,我们完全可以自己在OnPageChangeListener中的onPageScrolled中去实现自定义动画。
其实我也是最近看ViewPager的源码时,才发现了transformPage,并在官网上查阅了相关的资料,
之前一直是在OnPageChangeListener中的onPageScrolled中做的。
5.demo地址:
http://download.csdn.net/detail/u013384823/7894499
ps 第一次发博客,欢迎大家批评指正!