android中的Transition动画的使用

1. 简介

Transition框架是安卓4之后引入的一个转场框架。能够在场景转换时的加入转场动画(slide,fade等等)效果,使app更加炫酷。 这里须要注意的是Transition的用途有两种。php

  1. Activity和Activity之间, Fragment和Fragment之间,Activity和Fragment之间。
  2. 在一个ViewGroup内的布局变化。

2. 名词解释

还须要解释下关键的名词。 Scene: 一个布局场景 Transition: 两个场景间的动态变化,便可以理解为会产生动画效果java

当一个Scene到另外一个Scene时,Transition的职责为以下:android

  1. 获取先后两个Scene的状态
  2. 建立Animator,并计算动画效果,而后播放动画。

3. 相关动画类型

4. 动画的建立方法

4.1 xml文件

在res文件夹下建立一个transition文件夹。并在里面建立xml动画文件。git

<?xml version="1.0" encoding="utf-8"?>
<fade xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:interpolator/accelerate_decelerate" android:duration="200" android:transitionOrdering="sequential" />
复制代码

此时若是要在代码中引用该文件时能够用下面的方法。github

window.exitTransition = TransitionInflater.from(this).inflateTransition(R.transition.fade_transition)
复制代码

4.2 利用代码

window.exitTransition = 
    Slide().apply {
        duration = 200
        slideEdge = Gravity.END
    }
复制代码

4.3 建立多转场

利用xml:数据结构

<transitionSet xmlns:android="http://schemas.android.com/apk/res/android" android:transitionOrdering="together">
    <explode android:duration="1000" android:interpolator="@android:interpolator/accelerate_decelerate" />
    <fade android:duration="1000" android:fadingMode="fade_in_out" android:interpolator="@android:interpolator/accelerate_decelerate" />
    <slide android:duration="500" android:interpolator="@android:interpolator/accelerate_decelerate" android:slideEdge="top" />
</transitionSet>
复制代码

利用代码:app

val transitionSet = TransitionSet()
                transitionSet.addTransition(Fade())
                transitionSet.addTransition(Slide())
                transitionSet.setOrdering(ORDERING_TOGETHER)
复制代码

5. Activity之间的转场动画

5.1 各Activity的转场

A.exitTransition(): 从A到B时A的退出动画 B.enterTransition(): 从A到B时B的进场动画 B.returnTransition(): 从B返回A时的退出动画 A.reenterTransition(): 从B返回A时的进场动画框架

5.2 进场退场的过渡动画

  1. explore : 将View移入场景中心或从中移出。
  2. slide : 将视图从场景的其中一个边缘移入或移出。能够利用slideEdge=Gravity.Start方式设置移入移出边缘。
  3. fade : 经过更改视图的不透明度,在场景中添加视图或从中移除视图。

系统支持将任何扩展 Visibility 类的过渡做为进入或退出过渡。ide

5.3 转场设置

须要在activity的onCreate中设置转场动画。布局

window.let {
            // 设置分享元素的转场(后面会讲到)
            it.sharedElementEnterTransition
            it.sharedElementExitTransition
            it.sharedElementReenterTransition
            it.sharedElementReturnTransition
            
            // 设置是否需动画覆盖,转场动画中动画之间会有覆盖的状况
            // 能够设置false来让动画有序的进入退出
            it.allowEnterTransitionOverlap = false
            it.allowReturnTransitionOverlap = false
            
            // 设置activity之间的转场动画
// it.exitTransition = TransitionInflater.from(this).inflateTransition(R.transition.fade_transition)
            it.exitTransition = Slide().apply {
                duration = 200
                slideEdge = Gravity.END
            }
            it.enterTransition = Slide().apply {
                duration = 200
                slideEdge = Gravity.START

            }
            it.reenterTransition = Slide().apply {
                duration = 200
                slideEdge = Gravity.END
            }
            it.returnTransition = Slide().apply {
                duration = 200
                slideEdge = Gravity.START
            }
        }
复制代码

动画设置完了,下一步咱们是须要进行跳转的工做。 activity之间跳转须要用到intent, 若是须要它们之间传递数据是要用到Bundle。 没有错,咱们要设置的转场动画也要用到Bundle。咱们看一下下面的代码。

btn2.setOnClickListener {
    val intent = Intent()
    intent.setClass(this, ThirdActivity::class.java)
    // 利用ActivityOptions生成TransitionActivityOptions
    val transitionActivityOptions = ActivityOptions.makeSceneTransitionAnimation(
        this@MainActivity
    )
    // 利用上面生成的TransitionActivityOptions生成Bundle
    startActivity(intent, transitionActivityOptions.toBundle())
}
复制代码

6. Activity之间的元素共享转场

元素共享转场是Meterial设计中我的比较喜欢的设计之一。 activity之间的转场总有顿挫感,可是利用元素共享转场可让前一个画面中的元素能够在下一个画面上流畅的显示。

6.1 转场元素设置

1. 首先咱们须要让元素共享转场有效。

其实上面讲到过设置方法,以下。

window.let {
    // 设置分享元素的转场
    it.sharedElementEnterTransition
    it.sharedElementExitTransition
    it.sharedElementReenterTransition
    it.sharedElementReturnTransition
}
复制代码
2. 设置transitionName

要想让元素共享,须要让前一个画面的元素的id和后一个元素的id相同。 还有须要设置transitionName,设置的地方是layout的xml上。 固然,transitionName也须要先后一致。 以下。

<ImageView android:id="@+id/img" android:layout_width="240dp" android:layout_height="160dp" android:scaleType="fitCenter" android:src="@mipmap/android_logo" android:transitionName="img" // 就是这个 app:layout_constraintBottom_toTopOf="@id/txt" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_chainStyle="packed" />
复制代码

6.2 动画设置

咱们须要为转场元素设置动画。在activity的onCreatewindow上进行设置。

override fun onCreate(savedInstanceState: Bundle?) {
        // 为转场元素设置动画
        window.sharedElementEnterTransition = ChangeBounds()
        window.sharedElementExitTransition = ChangeBounds()
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
 }
复制代码

须要注意的是先后两个画面都须要为共享元素设置转场动画。固然动画能够是不同的,这个部分根据本身须要进行设置就行了。

6.3 进行转场

val intent = Intent()
val pair1 = Pair(imgView as View, imgView.transitionName)
val pair2 = Pair(textView as View, textView.transitionName)
intent.setClass(this, SecondActivity::class.java)
val transitionActivityOptions = ActivityOptions.makeSceneTransitionAnimation(
    this@MainActivity,
    pair1, pair2
)
startActivity(intent, transitionActivityOptions.toBundle())
复制代码

跟上面同样也是转换成Bundle进行转场的设置。 可是由于须要共享元素,ActivityOptions.makeSceneTransitionAnimation中加入共享元素信息。 这里须要用到的是Pair的数据结构,Pair的左边是共享的view,右边是刚刚设置的transitionName。 若是共享元素只有一个的状况能够直接使用以下方法。

val intent = Intent()
intent.setClass(this, SecondActivity::class.java)
val transitionActivityOptions = ActivityOptions.makeSceneTransitionAnimation(
    this@MainActivity,
    imgView as View, imgView.transitioName
)
startActivity(intent, transitionActivityOptions.toBundle())
复制代码

7. 一个画面的Scene转换

除了Activity之间的转换还有一个布局内的scene转换。

7.1 建立Scene

为两个布局建立Scene。

val scene1 = Scene.getSceneForLayout(sceneRoot, R.layout.scene1, this)
val scene2 = Scene.getSceneForLayout(sceneRoot, R.layout.scene2, this)
复制代码

除了上面的方法,也能够用下面方法进行建立。

scene1 = Scene.getSceneForLayout(sceneRoot,R.layout.scene_layout1,this)
scene2 = Scene.getSceneForLayout(sceneRoot,R.layout.scene_layout2,this)
复制代码

注意的是须要建立先后两个Scene的控件的ID相同。

7.2 切换Scene

建立Transition动画。

val transition =  TransitionInflater.from(this).inflateTransition(R.transition.slide_transition)
复制代码

利用TransitionManager进行Scene的切换。

TransitionManager.go(scene2, transition)
复制代码

7.3 完整的代码

// 建立Scene
val scene1 = Scene.getSceneForLayout(sceneRoot, R.layout.scene1, this)
val scene2 = Scene.getSceneForLayout(sceneRoot, R.layout.scene2, this)
var count = 1

btn.setOnClickListener {
    count = if (count == 1) {
    // 建立transition动画
    val transition =
TransitionInflater.from(this).inflateTransition(R.transition.slide_transition)
    // Scene切换
    TransitionManager.go(scene2, transition)
        2
    } else {
    val transition =
 TransitionInflater.from(this).inflateTransition(R.transition.slide_transition)
    TransitionManager.go(scene1, transition)
        1
    }
}
复制代码

8. 限制(来源:官方文档)

  • Android 版本在 4.0(API Level 14)4.4.2(API Level 19) 使用 Android Support Library’s
  • 应用于 SurfaceView 的动画可能没法正确显示。 SurfaceView 实例是从非界面线程更新的,所以这些更新与其余视图的动画可能不一样步。
  • 当应用于 TextureView 时,某些特定过渡类型可能没法产生所需的动画效果。
  • 扩展 AdapterView 的类(例如 ListView)会以与过渡框架不兼容的方式管理它们的子视图。若是您尝试为基于 AdapterView 的视图添加动画效果,则设备显示屏可能会挂起。
  • 若是您尝试使用动画调整 TextView 的大小,则文本会在该对象彻底调整过大小以前弹出到新位置。为了不出现此问题,请勿为调整包含文本的视图的大小添加动画效果。

github: github.com/HyejeanMOON…

相关文章
相关标签/搜索