Android 动画总结(1) - 概述
Android 动画总结(2) - 帧动画
Android 动画总结(3) - 补间动画
Android 动画总结(4) - 插值器
Android 动画总结(5) - 属性动画
Android 动画总结(6) - 估值器
Android 动画总结(8) - Activity 转场动画
Android 动画总结(9) - 过渡动画
LayoutAnimation
指定 ViewGroup 的子元素出场动画,作用在每个子元素上的动画是补间动画。
xml 方式
在 res/anim
目录创建 layout_anim.xml
文件
其中 item_anim 是一个普通的补间动画。
属性:
- android:animationOrder 控制子元素动画顺序
- normal 顺序
- reverse 逆序
- random 随机
- android:delay 子元素延长时间,默认是 0.5。比如 item_anim 这个动画的 duration 是 300ms,那么对于 0.2 的 delay 来说,每个子元素在前一个出现的基础上延时 0.2*300=60ms,即按照 animationOrder 控制的顺序,第一个子元素得 60 ms 后出现,第二个子元素 120ms 后出现,第三个子元素 180ms 后出现......
- android:animation 子元素所要执行的动画
然后对有子 View 的 ViewGroup 添加这个属性,比如 RecyclerView:
代码方式
其中子元素所用的补间动画代码方式前面已经说过,这里就直接用 xml 文件了。
val itemAnim = AnimationUtils.loadAnimation(ctx, R.anim.item_anim)
// val controller = LayoutAnimationController(itemAnim)
// controller.delay = 0.5f
val controller = LayoutAnimationController(itemAnim, 0.5f)
controller.order = LayoutAnimationController.ORDER_NORMAL
recycler.layoutAnimation = controller
LayoutTransition
在 3.0 以上版本中,如果给 ViewGroup 加上 android:animateLayoutChanges="true"
,布局变化时会自动加上默认的动画。
目前系统支持以下 5 种状态变化,可以为任意一种状态设置自定义动画:
- APPEARING:容器中出现一个视图
- DISAPPEARING:容器中消失一个视图
- CHANGING:布局改变导致某个视图随之改变,例如调整大小,但不包括添加或者移除视图
- CHANGE_APPEARING:其他视图的出现导致某个视图改变
- CHANGE_DISAPPEARING:其他视图的消失导致某个视图改变
private var count = 1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_layout_transition)
// setTransitionAnimator()
btnAdd.onClick {
val view = TextView(ctx)
view.text = "Text${count++}"
view.backgroundColor = Color.GRAY
view.padding = 20
rootView.addView(view)
}
btnRemove.onClick {
if (count-- > 1) {
rootView.removeViewAt(1)
}
}
}
支持自定义动画效果
@SuppressLint("ObjectAnimatorBinding")
private fun setTransitionAnimator() {
val transition = LayoutTransition()
// 为 ViewGroup 容器绑定 LayoutTransition 对象
rootView.layoutTransition = transition
// 使用翻转进入的动画代替默认的 APPEARING 动画
val appearAnim = ObjectAnimator
.ofFloat(null, "rotationY", 90f, 0f)
.setDuration(transition.getDuration(LayoutTransition.APPEARING) * 10)
transition.setAnimator(LayoutTransition.APPEARING, appearAnim)
// 使用滑动动画代替默认布局改变的动画
// 这个动画会让视图滑动进入并短暂地缩小一半,具有平滑和缩放的效果
val pvhSlide = PropertyValuesHolder.ofFloat("y", 0f, 1f)
val pvhScaleY = PropertyValuesHolder.ofFloat("scaleY", 1f, 0.5f, 1f)
val pvhScaleX = PropertyValuesHolder.ofFloat("scaleX", 1f, 0.5f, 1f)
val changingDisappearAnim = ObjectAnimator.ofPropertyValuesHolder(this, pvhSlide, pvhScaleY, pvhScaleX)
changingDisappearAnim.duration = transition.getDuration(LayoutTransition.CHANGE_DISAPPEARING)
transition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, changingDisappearAnim)
}
效果: