利用ViewPage的PagerTransformer定制页面切换效果 | 您所在的位置:网站首页 › 三国演义中谁草船借箭 › 利用ViewPage的PagerTransformer定制页面切换效果 |
利用ViewPage的PagerTransformer定制页面切换效果ViewPager动态添加删除及刷新页面ViewPager打造真正意义的无限轮播ViewPage 联动效果自带角标ViewPager禁止滑动和修改滑动速度
1. 简述
你是不是觉得 ViewPager 默认的切换效果有些平淡?其实,我们可以定制 ViewPager 的页面切换效果。定制 ViewPager 的页面切换效果,只需用到 ViewPager 的一个方法setPageTransformer(boolean reverseDrawingOrder, @Nullable PageTransformer transformer),实现一个接口 PageTransformer 。 2. PageTransformerPageTransformer 是 ViewPager 内部一个接口,源码如下: /** * A PageTransformer is invoked whenever a visible/attached page is scrolled. * This offers an opportunity for the application to apply a custom transformation * to the page views using animation properties. * 每当滚动到 可见/附属 页面时,都会调用 PageTransformer 。 * 这为应用程序提供了使用动画属性对页面视图应用自定义转换的机会。 *As property animation is only supported as of Android 3.0 and forward, * setting a PageTransformer on a ViewPager on earlier platform versions will * be ignored. */ 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. * 页面相对于当前正中位置的位置。0代表正中。1 是右边的一个完整页面位置, * -1 是左边的一个页面位置。 */ void transformPage(@NonNull View page, float position); }从源码注释我们可以看出, PageTransformer 就是为自定义页面切换效果而生的。 使用 PageTransformer 需要实现方法 void transformPage(@NonNull View page, float position),这个方法有两个参数,两个参数是对应关系,position 表示页面相对于正中(0)的位置,0代表正中,1 是右边的一个完整页面位置,-1 是左边的一个页面位置。 如下图所示,ViewPager 页面滑动过程中,屏幕中显示 2 个页面,即左边页面(绿色)的一部分和右边页面(蓝色)的一部分。以虚线和页面左边缘作为位置参考,那么左边页面位置在 (-1, 0) 区间,右边页面位置在 (0, 1) 区间。它们的值是:position左 = (x左 - x0) / width,position右 = (x右 - x0) / width。 可以调用 ViewPager 的 setOffscreenPageLimit(int) 方法设置了离屏缓存页面数量(空闲时,当前页面左右保留页面数量)。 如果想在 ViewPager 中显示多个页面,可以: 调用 setOffscreenPageLimit(int) 设置离屏缓存页面数量 大于 1;给 ViewPager 外层控件以及 ViewPager 都设置 android:clipChildren="false";给 ViewPager 设置 适当的 leftMargin 和 rightMargin 。 3. 例子和效果1、手风琴效果 2、下弧形效果 3、上弧形效果 4、立方翻转-外 使用: mPageTransformer = new CubicOverturnTransformer(90f, 0.6f); mVpImgs.setPageTransformer(reverseDrawingOrder, mPageTransformer);最大旋转角度 90 度,最小缩放到 0.6 。 5、立方翻转-内 与上一个效果是同一套代码,绕 Y 轴旋转方向相反,使用时,让 最大旋转角度小于 0 即可,如下代码所示,最大旋转角度改为 -90f 就是内部翻转: 使用: mPageTransformer = new CubicOverturnTransformer(-90f, 0.6f); mVpImgs.setPageTransformer(reverseDrawingOrder, mPageTransformer);最大旋转角度 90 度,最小缩放到 0.6 。 6、下沉效果 特殊的缩放效果,有最小缩放值,页面缩到最小值不再缩小,同时有透明度的变化(可以去掉透明度变化)。 旋转中心位置的调整主要是为了调整页面间隙。 /** * 下沉效果 */ public class DipInTransformer implements ViewPager.PageTransformer { private static final float MIN_SCALE = 0.85f; private float mMinScale = MIN_SCALE; private static final float MIN_ALPHA = 0.5f; private float mMinAlpha = MIN_ALPHA; @Override public void transformPage(@NonNull View page, float position) { Log.i("DipInTransformer", "transformPage: id = " + page.getId() + ", position = " + position); int pageWidth = page.getWidth(); int pageHeight = page.getHeight(); // page.setPivotX(pageWidth * 0.5f); page.setPivotY(pageHeight * 0.5f); if (position //(-1, 1) float scaleFactor = Math.max(mMinScale, 1 - Math.abs(position)); page.setScaleX(scaleFactor); page.setScaleY(scaleFactor); if (position page.setPivotX(pageWidth * (0.5f - 0.5f * scaleFactor)); } page.setAlpha(mMinAlpha + (scaleFactor - mMinScale) / (1f - mMinScale) * (1f - mMinAlpha)); } else {//(1, +Infinity) page.setAlpha(mMinAlpha); page.setScaleX(mMinScale); page.setScaleY(mMinScale); page.setPivotX(pageWidth * 0f); } } }7、淡入淡出效果(透明度) 8、水平翻转效果(左右翻转) 即以水平中心线为旋转中心,绕 Y 轴旋转。代码如下所示,同样要注意镜头距离: /** * 水平翻转效果 */ public class FlipHorizontalTransformer implements ViewPager.PageTransformer { @Override public void transformPage(@NonNull View page, float position) { page.setCameraDistance(getCameraDistance()); page.setTranslationX(-page.getWidth() * position); float rotation = 180f * position; page.setAlpha(rotation > 90f || rotation -0.5f && position page.setVisibility(View.INVISIBLE); } } private float getCameraDistance() { DisplayMetrics displayMetrics = VpsApplication.getAppContext().getResources().getDisplayMetrics(); float density = displayMetrics.density; int widthPixels = displayMetrics.widthPixels; int heightPixels = displayMetrics.heightPixels; return 1.5f * Math.max(widthPixels, heightPixels) * density; } }9、竖直翻转效果(上下翻转) 即以竖直中心线为旋转中心,绕 X 轴旋转。代码如下所示,同样要注意镜头距离: /** * 竖直翻转效果 */ public class FlipVerticalTransformer implements ViewPager.PageTransformer { @Override public void transformPage(@NonNull View page, float position) { page.setCameraDistance(getCameraDistance()); page.setTranslationX(-page.getWidth() * position); float rotation = 180f * position; page.setAlpha(rotation > 90f || rotation -0.5f && position page.setVisibility(View.INVISIBLE); } } private float getCameraDistance() { DisplayMetrics displayMetrics = VpsApplication.getAppContext().getResources().getDisplayMetrics(); float density = displayMetrics.density; int widthPixels = displayMetrics.widthPixels; int heightPixels = displayMetrics.heightPixels; return 1.5f * Math.max(widthPixels, heightPixels) * density; } }10、浮出效果 让所有右边页面都移动到 正中位置,从右向左滑动切换页面时,左边从右向左滑出,右边页面放大淡入。 /** * 浮出效果 */ public class RiseInTransformer implements ViewPager.PageTransformer { private static final float DEF_MIN_SCALE = 0.72f; private float mMinScale = DEF_MIN_SCALE; private static final float DEF_MIN_ALPHA = 0.5f; public RiseInTransformer() { } public RiseInTransformer(float minScale) { this.mMinScale = minScale; } public float getMinScale() { return mMinScale; } public void setMinScale(float minScale) { this.mMinScale = minScale; } @Override public void transformPage(@NonNull View page, float position) { if (position page.setTranslationX(-position * page.getWidth()); page.setScaleX(1f - (1f - mMinScale) * position); page.setScaleY(1f - (1f - mMinScale) * position); page.setAlpha(1f - (1f - DEF_MIN_ALPHA) * position); } else { page.setTranslationX(-position * page.getWidth()); page.setScaleX(mMinScale); page.setScaleY(mMinScale); page.setAlpha(DEF_MIN_ALPHA); } } }调用时需要反转绘制顺序,即 reverseDrawingOrder = true,使左边页面先绘制,右边页面后绘制,否则效果无法实现。 int reverseDrawingOrder = true; mVpImgs.setPageTransformer(reverseDrawingOrder , mPageTransformer);11、下潜效果 让所有左边页面都移动到 正中位置,切换页面时,左边页面缩小淡出,右面页面从右向左滑入正中。 /** * 下潜效果 */ public class DiveOutTransformer implements ViewPager.PageTransformer { private static final float DEF_MIN_SCALE = 0.72f; private float mMinScale = DEF_MIN_SCALE; private static final float DEF_MIN_ALPHA = 0.5f; public DiveOutTransformer() { } public DiveOutTransformer(float minScale) { this.mMinScale = minScale; } public float getMinScale() { return mMinScale; } public void setMinScale(float minScale) { this.mMinScale = minScale; } @Override public void transformPage(@NonNull View page, float position) { if (position page.setTranslationX(-position * page.getWidth()); page.setScaleX(1f + (1f - mMinScale) * position); page.setScaleY(1f + (1f - mMinScale) * position); page.setAlpha(1f + (1f - DEF_MIN_ALPHA) * position); } else { page.setTranslationX(0f); } } }调用时不需要反转绘制顺序,即 reverseDrawingOrder = false,使右边页面先绘制,左边页面后绘制,否则效果无法实现。 int reverseDrawingOrder = false; mVpImgs.setPageTransformer(reverseDrawingOrder , mPageTransformer);12、堆叠效果 所有右边页面移动到正中位置,即 0 位置,滑动时,把最上面页面滑掉,代码如下所示: /** * 堆叠效果 */ public class StackTransformer implements ViewPager.PageTransformer { @Override public void transformPage(@NonNull View page, float position) { page.setTranslationX(position if (position //[-1, 1] if (position //[0, 1] page.setScaleX(1f - (1f - mMinScale) * position); page.setScaleY(1f - (1f - mMinScale) * position); } } else {//(1, +Infinity] page.setScaleX(mMinScale); page.setScaleY(mMinScale); } } }并行覆盖效果 通过调用 View 的 setScrollX() 方法,使页面内容随着 position 移动。 public class ParallaxTransformer implements ViewPager.PageTransformer { @Override public void transformPage(@NonNull View page, float position) { int width = page.getWidth(); if (position if (position page.setScrollX((int) (width * 0.75f * position)); } } else { page.setScrollX(0); } } }调用时需要反转绘制顺序,即 reverseDrawingOrder = true,使左边页面先绘制,右边页面后绘制,否则效果无法实现。 int reverseDrawingOrder = true; mVpImgs.setPageTransformer(reverseDrawingOrder , mPageTransformer); 项目地址https://github.com/wangzhengyangNo1/ViewPagerSerialDemo 4. 参考【1】巧用ViewPager 打造不一样的广告轮播切换效果 【2】ViewPager 超详解:玩出十八般花样 【3】关于ViewPager.PageTransformer的一些理解 【4】一个卡片式的ViewPager,带你玩转ViewPager的PageTransformer属性! |
CopyRight 2018-2019 实验室设备网 版权所有 |