美文网首页安卓面试Android技术知识Android开发
Android ViewPager多屏显示、切换动画,让你的轮播

Android ViewPager多屏显示、切换动画,让你的轮播

作者: Android小Y | 来源:发表于2019-03-31 20:34 被阅读98次

    前言

    在Android中,ViewPager可以用来做页面切换,同时也可以实现基本的轮播效果,之前也对轮播做了个封装 ViewPager封装轮播效果+指示器 实现一行代码展示轮播图,但我们经常可以看到一些App的轮播效果会多样化,有些的效果会是左右两屏也各显示一部分,让用户明显感知到左右还有东西可以切换,另外有的还会加上一些切换动画,比如正中间是放大,左右两屏是稍微缩小,每次切换时,滑到中间时总会有放大效果。如下:

    示意图

     

    ViewPager如何实现一屏多图显示?

    ViewPager提供了一个setPageMargin方法,允许我们设置ViewPager的Item之间的间隔:

    ViewPager viewPager = (ViewPager)findViewById(R.id.view_pager);
    viewPager.setPageMargin(64);
    

    设置之后会是如下效果:


    setPageMargin.gif

    可以看到两边都有了边距,但是注意:这个边距是在中间图片的范围之外的,也就是说,假如我们的Item的宽度是填充屏幕两边的话,那这个边距只有在拖动时才能看得到,否则当ViewPager不滑动时,这块区域是在屏幕外的。

    但这不是我们想要的效果,如何让这个边距显示在屏幕内呢?可以为ViewPager设置一个margin值,并且这个margin值要比setPageMargin设置的值还大,并且为ViewPager设置setClipChildren为false,让它不裁剪Item,由于setPageMargin比margin小,所以两边就都能露出一点空间显示出来。

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipChildren="false"
        >
    
        <android.support.v4.view.ViewPager
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:layout_marginLeft="64dp"
            android:layout_marginRight="64dp"
            android:layout_marginTop="16dp"
            android:layout_marginBottom="16dp">
    
        </android.support.v4.view.ViewPager>
        
    </FrameLayout>
    

    记得ViewPager的父布局和它本身都要设置setClipChildren为false,以允许子View在父View的范围外显示。并且viewPager的setOffscreenPageLimit要设置为3以上,否则两边的Item都没有预加载,没法显示。

    viewPager.setOffscreenPageLimit(3);
    viewPager.setPageMargin(32);
    viewPager.setClipChildren(false);
    

    效果如下:


    ViewPager多屏显示

     

    如何为ViewPager添加切换动画?

    Android在3.0之后提供了ViewPager设置切换动画的接口——PageTransformer,只要实现这个接口,重写它的transformPage(View view, float position)方法,然后通过ViewPager的setPageTransformer设置给ViewPager,即可自定义动画效果。

    public class CustomPageTransformer implements ViewPager.PageTransformer {
        @Override
        public void transformPage(View view, float position) {
            //这里自定义动画
        }
    }
    

    transformPage方法有两个参数,第一个参数是一个View,第二个参数是一个float类型的值,它不是代表ViewPager的Item的position位置,而是代表当前滑动状态。它有三个临界值-1 0 1。当ViewPager右滑时,两个参数代表的意义如下:

    当position返回值为0时,代表这个View刚好移动到正中间。
    当position返回值为0~1时,代表这个View准备从左向右移动离开屏幕,移动停止时,position刚好等于1
    当position返回值为-1~0时,代表这个View准备从左向右进入屏幕,移动停止时,position刚好等于0

    所以我们可以通过这个方法控制每次切换时的动画过程,比如说一个切换时放大的效果,可以在transformPage中判断position的值。如果是-1到0的话,就说明当前这个View是准备进入屏幕,那我们应该给它一个逐渐放大的动画,如果是0到1的话,说明当前这个View是准备离开屏幕,就该给它设置一个逐渐缩小的动画,当position等于0时,要处于最大的状态:

    public class ScalePageTransformer implements ViewPager.PageTransformer {
        //最小状态时,Size缩小为90%
        private static final float MIN_SCALE = 0.9F;
    ![banner切换动画效果图.gif](https://img.haomeiwen.com/i16311248/ab59737f9fb15304.gif?imageMogr2/auto-orient/strip)
    
        @Override
        public void transformPage(View view, float position) {
            float scale = Math.max(MIN_SCALE,1 - Math.abs(position));
            if (position < -1.0f) {
                view.setScaleY(MIN_SCALE);
            } else if (position <= 0.0f) {
                view.setScaleY(scale);
            } else if (position <= 1.0f) {
                view.setScaleY(scale);
            } else {
                view.setScaleY(MIN_SCALE);
            }
        }
    }
    

    当position处于(-1,1)这个范围之外时,说明它在当前屏幕中是完全不可见的,肯定应该处于最小的状态。当position处于(-1,0)或者(0,1)之间时,1-Math.abs(position)的变化是在0和1之间,当它比0.9还小时,就取0.9,如果比0.9大,就用它来作为当前放大的比例(也就是说控制放大比例在90%到100%之间),当position刚好等于0时,View刚好滑到最中间,scale就应该为1,也就是最大的状态。

    然后将我们的PageTransformer设置给ViewPager:

    viewPager.setPageTransformer(true, new ScalePageTransformer());
    

     
    这样我们的切换放大效果就出来了:


    ViewPager切换放大效果.gif

     

    更多动画效果

    上面以放大效果做个例子,所以这也体现出Google设计的精妙之处,把动画效果的具体实现与ViewPager解耦开来,并且根据positionview两个参数联动,然后结合View的属性api比如setScale和setRotate、setAlpha等等,可以定义出各种各样的切换动画,比如下面这些效果:



    将它们封装成了一个BannerView,源码和demo均已上传到 GitHub-YBannerView

     

    欢迎关注 Android小Y 的简书,更多Android精选自定义View

    Android 玩转PathMeasure之自定义支付结果动画
    Android 自定义弧形旋转菜单栏——卫星菜单
    Android 自定义带入场动画的弧形百分比进度条

    GitHubGitHub-ZJYWidget
    CSDN博客IT_ZJYANG
    简 书Android小Y
    在Github上建了一个集合炫酷自定义View的项目,里面有很多实用的自定义View源码及demo,会长期维护,欢迎Star~ 如有不足之处或建议还望指正,相互学习,相互进步,如果觉得不错动动小手给个Star, 谢谢~

    关注Android 技术小栈,更多精彩原创

    相关文章

      网友评论

        本文标题:Android ViewPager多屏显示、切换动画,让你的轮播

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