Android 使用自定义PageTransformer实现ViewPager切换动画

本文没有提供酷炫的动画实现,而是分析理解如何使用自定义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切换动画的分析到此结束,知道原理后其他炫酷动画效果自然就简单了。

      </div>
    </div>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值