自定义ViewPager切换动画

作者: vison123 | 来源:发表于2017-09-25 11:56 被阅读89次

    前言

    我们都知道项目里的广告轮播大部分都是viewpager做的,viewpager的使用也是非常简单的,相信大家都会用,但是大部分应用的广告轮播都是前篇一律的普通的切换效果。我们是否有想过改变一下这个轮播的切换动画呢。今天我们就来分析下viewpager的一个方法。没错了,就是实现ViewPager.PageTransformer这个接口,这个接口只有一个方法transformPage(View view, float position) ,通过重写这个方法,就可以轻松地实现这个实现各种炫酷的切换动画效果~~

    正文

    自己先写了几个效果图,先来瞅瞅长啥样。

    image.png

    哈哈,开个玩笑,来看看这些动画吧。

    广告切换效果 翻书效果 引导图切换效果

    看到这里,大家应该就知道通过这个接口,我们可以实现很多好看的动画效果了吧。

    使用步骤

    • 自定义PageTransformer类,实现ViewPager.PageTransformer这个接口,重写方法transformPage(View view, float position)
    • 调用ViewPagerd的setPageTransformer(boolean reverseDrawingOrder, PageTransformer transformer) 这个方法即可。
      可以看到,使用时非常简单的。今天我们主要是来看看重写PageTransforme这个类到底是怎么使用的。

    自定义PageTransformer类

    自定义PageTransformer类,我拿一个例子来说明一下它的做法,就拿这个广告切换的轮播效果看看吧,


    广告切换效果
    • 首先可以看到这个viewpger是多屏显示的,一般来说viewpager都是单屏显示的,这里要用介绍一下clipChildren属性。

    clipchildren

    含义

    是否允许子View超出父View的返回,有两个值true 、false ,默认true
    使用的时候给子View和根节点View控件都设置android:clipChildren="false",那么这个子View就不会限制在父View当中

    • viewpager使用示例
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:gravity="center"
                  android:clipChildren="false"
                  android:orientation="vertical">
        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="250dp"
            android:layout_height="400dp"
            android:clipChildren="false"
           ></android.support.v4.view.ViewPager>
    </LinearLayout>
    

    实现的效果大体是这样的

    image.png

    代码我就不贴了,自己写写看看~
    下面讲讲切换效果是怎么实现的。

    切换效果实现

    这里主要是分析transformPage(View view, float position),我们来看看view参数和position参数
    我是自己打日志看的,分析一下左滑和右滑的情况【看着效果图实现】

    image.png
    • 左滑【从A到B】
      这时候发现A的position的变化是从0-1之间变化,B的position参数是从10之间变化
    • 右滑【从C到B】
      这时候发现B的position的变化是从-10之间变化,C的position参数是从01之间变化。
    • 结论
      也也就是说左边那个view的参数始终是从0和-1之间变化的,而右边那个view的参数始终是从0到1之间变化的。小于等于-1的时候即在最左边,大于等于1的时候即在最右边。
    • 模板代码如下
     if (position <= -1) {//超出最左边,此时不可见隐藏即可
                // TODO
            } else if(position > -1 && position < 0){//左边的view
                // TODO
            } else if (position < 1 && position >= 0) {//右边的view
              // TODO
            } else {//超出最右边,此时不可见隐藏即可
              // TODO
            }
    

    知道这个变化就好办了,来看看效果图的变化
    定义的几个常量

     private static final float MIN_WIDTH_SCALE = 0.65f;//宽度最小缩小比例
     private static final float MIN_HEIGHT_SCALE = 0.6f;//高度最小缩小比例
     private static final float MIN_ALPHA = 0.5f;//最小透明度
    

    接下来分析从A到B

    左边view的scaleX的变化

    • 最左边的时候宽度为原宽度的0.6倍【此时position的值为-1】
    • 原位置的时候宽度为原宽度【此时position的值为0】
    scaleX的变化函数如图
    所以可以得出左边view的ScaleX的值得变化为
    scaleX = (1 - MIN_WIDTH_SCALE) * position + 1
    相应的算出
    scaleY = (1 - MIN_HEIGHT_SCALE) * position + 1
    alpha = 1 - MIN_ALPHA) * position + 1

    右边view的scaleX的变化

    • 原位置的时候宽度为原宽度【此时position的值为1】
    • 最右边的时候宽度为原宽度的0.6倍【此时position的值为0】
    scaleX的变化函数如图
    所以可以得出右边view的ScaleX的值得变化为
    scaleX = 1 - (1 - MIN_WIDTH_SCALE) * position
    相应的算出
    scaleY = 1 - (1 - MIN_HEIGHT_SCALE) * position
    alpha = 1 - (1 - MIN_ALPHA) * position

    完整代码

    public class ZoomOutTransformer implements ViewPager.PageTransformer {
    
        private static final float MIN_WIDTH_SCALE = 0.65f;//宽度最小缩小比例
        private static final float MIN_HEIGHT_SCALE = 0.6f;//高度最小缩小比例
        private static final float MIN_ALPHA = 0.5f;//最小透明度
    
        @Override
        public void transformPage(View view, float position) {
            int pageWidth = view.getWidth();
    
            if (position <= -1) {//超出最左边
                view.setAlpha(MIN_ALPHA);
                view.setScaleX(MIN_WIDTH_SCALE);
                view.setScaleY(MIN_HEIGHT_SCALE);
            } else if(position > -1 && position < 0){//左边view
                //float fraction = position + 1;
                view.setScaleX((1 - MIN_WIDTH_SCALE) * position + 1);
                view.setScaleY((1 - MIN_HEIGHT_SCALE) * position + 1);
                view.setAlpha((1 - MIN_ALPHA) * position + 1);
            } else if (position < 1 && position >= 0) {//右边view
                view.setAlpha(1);
                view.setScaleX(1 - (1 - MIN_WIDTH_SCALE) * position);
                view.setScaleY(1 - (1 - MIN_HEIGHT_SCALE) * position);
                view.setAlpha(1 - (1 - MIN_ALPHA) * position);
            } else {//超出最右边
                view.setAlpha(MIN_ALPHA);
                view.setScaleX(MIN_WIDTH_SCALE);
                view.setScaleY(MIN_HEIGHT_SCALE);
            }
        }
    }
    

    结语

    使用是不是相当简单呀,通过这个可以做出很多动画效果,来看看结合这个实现的App广告轮播吧


    今天就写到这里了,enjoy it~
    源代码

    相关文章

      网友评论

        本文标题:自定义ViewPager切换动画

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