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

xiaoxiao2021-02-28  45

本文没有提供酷炫的动画实现,而是分析理解如何使用自定义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(这与ViewPager的OnPageChangeListener回调方法中的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>
转载请注明原文地址: https://www.6miu.com/read-2613393.html

最新回复(0)