在开发中我们使用过渡动画,平时会用ObjectAnimator
或ValueAnimator
来完成。
但其实,我们可以用更简单的方式来实现同样的效果。
这就是TransitionManager,Google已经帮我们封装好了。
首先,我们创建一个布局
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/img_01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_margin="24dp"
android:src="@mipmap/ic_01" />
FrameLayout>
然后在代码里动态改变他的布局属性
img01.setOnClickListener {
val lp = img01.layoutParams as FrameLayout.LayoutParams
lp.gravity = Gravity.RIGHT
img01.requestLayout()
}
运行项目,我们可以看到效果
可以看到,我们点击小车的时候,小车的位置进行了改变。
但是这没有达到我们想要的动画效果,那要怎么办呢 ?
很简单,加上以下一句话,就自动会有动画效果了。
img01.setOnClickListener {
TransitionManager.beginDelayedTransition(img01.parent as ViewGroup?)
val lp = img01.layoutParams as FrameLayout.LayoutParams
lp.gravity = Gravity.RIGHT
img01.requestLayout()
}
除了动态改变view的属性,我们还可以直接替换xml布局文件,来实现过渡动画。
首先,我们需要先新建开始和结束的xml文件,注意这里的id要保持一致。
activity_main_start.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/root"
tools:context=".MainActivity">
<ImageView
android:id="@+id/img_01"
android:layout_width="200dp"
android:layout_height="300dp"
android:scaleType="centerCrop"
android:src="@mipmap/img_01"/>
FrameLayout>
activity_main_end.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/root"
tools:context=".MainActivity">
<ImageView
android:id="@+id/img_01"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@mipmap/img_01"/>
FrameLayout>
接着,在代码里调用TransitionManager.go
override fun onClick(v: View) {
val root = findViewById<ViewGroup>(R.id.root)
val startScene = Scene.getSceneForLayout(root, R.layout.activity_main_start, this)
val endScene = Scene.getSceneForLayout(root, R.layout.activity_main_end, this)
if (toggle) {
TransitionManager.go(endScene, ChangeBounds())
} else {
TransitionManager.go(startScene, ChangeBounds())
}
bindData() //需要重新设置点击事件,因为在动画开始的一瞬间,原来的View已经从布局中移除
toggle = !toggle
}
private fun bindData() {
img01 = findViewById(R.id.img_01)
img01.setOnClickListener(this)
}
这让人感到很神奇,TransitionManager做了些什么了 ?
下篇文章我们来看下它的源码。
Android TransitionManager源码解析