Android 动画总结(7) - ViewGroup 子元素间的动画

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 种状态变化,可以为任意一种状态设置自定义动画:

  1. APPEARING:容器中出现一个视图
  2. DISAPPEARING:容器中消失一个视图
  3. CHANGING:布局改变导致某个视图随之改变,例如调整大小,但不包括添加或者移除视图
  4. CHANGE_APPEARING:其他视图的出现导致某个视图改变
  5. 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)
}

效果:

Android 动画总结(7) - ViewGroup 子元素间的动画_第1张图片
2018_03_31_18_13_43.gif

你可能感兴趣的:(Android 动画总结(7) - ViewGroup 子元素间的动画)