自定义ViewPager切换动画

转载请注明出处:http://blog.csdn.net/u013384823/article/details/39187709

做Android开发有一年多了,以前一直用云笔记;现在觉得该学会分享了,并坚持下去!

废话不多说,直接进入正题:

自定义ViewPager切换动画_第1张图片

上面是微信的主页切换效果图,随着手指的滑动,两个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.效果图如下:

 自定义ViewPager切换动画_第2张图片              自定义ViewPager切换动画_第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 第一次发博客,欢迎大家批评指正!

你可能感兴趣的:(Android,View)