前言

在平常的开发中,咱们往往需要做一些页面、布局相关的切换作用,曾经写过一篇转场相关的动画的文章juejin.cn/post/719956…
但这是比较重量级,有时候咱们做fragment切换或者一些控件切换做联接动画,想要比较便利的完成,其实ViewPager就供给了切换动画的办法,并且运用起来也十分的便利,扩展性还很不错,简略来说便是你能够用简略的办法去完成你自界说的控件切换作用。

1. 运用办法

运用十分简略

viewpager.setPageTransformer(CardPageTransformer())

直接调用viewpager的setPageTransformer办法,传一个PageTransformer,而这个PageTransformer需要咱们自界说,具体完成切换动画作用的地方也是在这儿面

Android ViewPager切换动画

在transformPage办法中写具体的动画作用

2. 部分动画作用

为了便利运用,官方也现已供给一些根底的动画作用给开发者运用

能够参考developer.android.google.cn/develop/ui/…

假如你要完成的作用是在里面的,你能够直接拷贝它的代码来运用,这是最便利的办法。

当然,除了运用官方列举出的一些根底作用之外,你还能够界说自己的作用。咱们能够来看看一个卡片切换的作用,代码便是上面的运用列举的demo

class CardPageTransformer : ViewPager2.PageTransformer {
    var mScaleOffset = 200f  
    var mTranslationOffset = 100f  
    override fun transformPage(page: View, position: Float) {  
        if (position <= 0f) {  
            page.translationX = 0f  
        } else {  
            val pageWidth: Int = page.width  
            val transX = -pageWidth * position + mTranslationOffset * position  
            page.translationX = transX  
            val scale: Float = (pageWidth - mScaleOffset * position) / pageWidth.toFloat()  
            page.scaleX = scale  
            page.scaleY = scale  
            page.translationZ = -position  
        }  
    }  
}

能够看看作用

咱们也能够用别的一种办法更直观的去完成

class DepthPageTransformer : ViewPager2.PageTransformer {
    private val MIN_SCALE = 0.75f  
    override fun transformPage(page: View, position: Float) {  
        page.apply {  
            val pageWidth = width  
            when {  
                position < -1 -> {  
                    alpha = 0f  
                }  
                position <= 0 -> {  
                    alpha = 1f  
                    translationX = 0f  
                    translationZ = 0f  
                    scaleX = 1f  
                    scaleY = 1f  
                }  
                position <= 1 -> {  
                    alpha = 1 - position  
                    translationX = pageWidth * -position  
                    translationZ = -1f  
                    val scaleFactor = (MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position)))  
                    scaleX = scaleFactor  
                    scaleY = scaleFactor  
                }  
                else -> {  
                    alpha = 0f  
                }  
            }  
        }  
    }  
}

看看作用

能够看到两个的作用差不多,但是第二个demo写了if-else判别会比较好理解一点。

2. transformPage办法

上面说了,自界说切换动画作用的办法便是用transformPage,该办法有两个参数,View类型的page和Float类型的position

上面的第二个Demo能够看出,它是依据position的4个不同的区间做操作。那么这个pager是什么,position又是什么呢?

咱们能够去看接口的阐明

Android ViewPager切换动画

嗯~ 看完之后仍是有点懵,没事,咱们能够写个空的PageTransformer然后加打印看看这个切换的进程

class EmptyPageTransformer : ViewPager2.PageTransformer {
    override fun transformPage(page: View, position: Float) {  
        Log.v("mmp","==== ${page.tag} ${position}")  
    }  
}

PS:我给每个view设置了不同的tag,便利打印

从页面1切换到页面2的进程能够看到

Android ViewPager切换动画

其实看这个打印是不是现已很明显了,你能看到这个进程有两个view都有回调到这个办法,一眼你就能理解是切换的两个view吗,而tag为0的view的position是从0到-1,tag为1的view的position是从1到1。

那从这儿你就能很明显的得到这些信息,这个进程涉及两个控件,所以要有个View类型的page字段表明当时操作的是哪个控件。position是用float类型表明的进展。除此之外,你还能发现一个特点“方向”,从0-1是左滑,从1-0是右滑。

所以在上面的操作之后,假如再进行左滑,你能够大胆的估测,tag为0的view的position会从-1到0,tag为1的view的position会从0到1。咱们能够看看是不是这样

Android ViewPager切换动画

能够看到结果正如咱们预料的那样。

3. 开始自界说动画

知道了transformPage的参数的含义之后,咱们就能十分便利的完成咱们自界说的切换动画作用。当然这个进程需要一定的想象力。

通过进展position,去逐渐改动view的一些特点(alpha、translation等等),这是不是瞬间就有点特点动画的意思了

刚开始不熟的话,咱们能够按照第二个Demo那样子给position去分区间判别,就不简单紊乱。

能够试着随便写一个旋转作用(一般这种横向切换也不会做旋转作用)

class NewPageTransformer : ViewPager2.PageTransformer {
    override fun transformPage(page: View, position: Float) {  
        page.apply {  
            pivotY = (page.height / 2).toFloat()  
            pivotX = (page.width / 2).toFloat()  
            val w = width  
            when {  
                position < -1 -> {  
                }  
                position <= 0 -> {  
                    rotation = -90 * position  
                    translationX = -w * position  
                }  
                position <= 1 -> {  
                    rotation = -90 * position  
                    translationX = w * position  
                }  
                else -> {  
                }  
            }  
        }  
    }  
}

能够看看作用

Android ViewPager切换动画

一般也不会做这种古怪的作用,这儿只是为了便利演示