美文网首页Android技术知识安卓资源收集Android
Android 使用自定义PageTransformer实现Vi

Android 使用自定义PageTransformer实现Vi

作者: 逍遥wqy | 来源:发表于2016-08-07 15:56 被阅读4674次

    本文没有提供酷炫的动画实现,而是分析理解如何使用自定义PageTransformer完成要想的效果。

    1、PageTransformer之position分析

    从3.0开始,ViewPager开始支持自定义切换动画,官方提供的接口为PageTransformer,因此只要实现该接口即可,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 view, float position)
    

    transformPage()方法的关键在于position的理解,从doc注释来看,当前选中的item的position永远是0(这与ViewPagerOnPageChangeListener回调方法中的position不同),被选中item的前一个为-1,被选中item的后一个为1。** 其实这里文档的描述并不是完全正确的,前后item position为-1和1的前提是你没有给ViewPager设置pageMargin(通过调用viewPager.setPageMargin(int)方法设置)**。如果你设置了pageMargin,前后item的position需要分别加上(或减去,前减后加)一个偏移量(偏移量的计算方式为pageMargin / pageWidth)。
    在用户滑动界面的时候,position是动态变化的,下面以左滑为例:

    • 选中item position:0->-1 - offset (pageMargin / pageWidth)
    • 前一个item position:-1 - offset (pageMargin / pageWidth) -> -2 - offset (pageMargin / pageWidth),再往前就以此类推
    • 后一个item position:1 + offset (pageMargin / pageWidth) -> 0,再往后就以此类推

    因此我们可以将position的值应用于setAlpha(), setTranslationX(), 或者 setScaleY()等等方法,从而实现自定义的动画效果。

    2、示例代码

    2.1 布局文件

    先看下布局,只有一个RelativeLayout,内部放置了一个ViewPager

    <RelativeLayout
        android:id="@+id/viewpager_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:clipChildren="false">
    
        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="200dp"
            android:layout_height="280dp"
            android:clipChildren="false"
            android:layout_centerInParent="true">
        </android.support.v4.view.ViewPager>
    </RelativeLayout>
    

    为了ViewPager可以展示多个Item,这里分别设置其以及其父布局的clipChildren属性为false。

    2.2 滑动技巧

    ViewPager滑动还有一个小技巧,我们都知道默认情况下ViewPager本身滑动才可以切换页面,所以就算屏幕上显示了多个item,当你滑动未被选中的item时,ViewPager也是无法切换页面的。如果想扩大滑动区域可以给ViewPager的父布局设置触摸监听,并将触摸事件交给ViewPager处理,这样即使滑动触摸位置为未选中item,ViewPager仍然可以相应滑动了。代码如下:

    relativeLayout = (RelativeLayout) view.findViewById(R.id.viewpager_container);
    relativeLayout.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return viewPager.onTouchEvent(event);
        }
    });
    

    2.3 自定义PageTransformer

    class MyPageTransform implements ViewPager.PageTransformer {
    
        final float SCALE_MAX = 0.8f;
        final float ALPHA_MAX = 0.5f;
    
        @Override
        public void transformPage(View page, float position) {
            float scale = (position < 0)
                    ? ((1 - SCALE_MAX) * position + 1)
                    : ((SCALE_MAX - 1) * position + 1);
            float alpha = (position < 0)
                    ? ((1 - ALPHA_MAX) * position + 1)
                    : ((ALPHA_MAX - 1) * position + 1);
            //为了滑动过程中,page间距不变,这里做了处理
            if(position < 0) {
                ViewCompat.setPivotX(page, page.getWidth());
                ViewCompat.setPivotY(page, page.getHeight() / 2);
            } else {
                ViewCompat.setPivotX(page, 0);
                ViewCompat.setPivotY(page, page.getHeight() / 2);
            }
            ViewCompat.setScaleX(page, scale);
            ViewCompat.setScaleY(page, scale);
            ViewCompat.setAlpha(page, Math.abs(alpha));
        }
    }
    

    2.3 实现效果

    device-2016-08-07-153455.gif
    自定义PageTransformer实现ViewPager切换动画的分析到此结束,知道原理后其他炫酷动画效果自然就简单了。

    相关文章

      网友评论

        本文标题:Android 使用自定义PageTransformer实现Vi

        本文链接:https://www.haomeiwen.com/subject/apslsttx.html