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

2018-04-01  本文已影响0人  三流之路

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 文件

<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
    android:delay="0.2"
    android:animationOrder="normal"
    android:animation="@anim/item_anim" />

其中 item_anim 是一个普通的补间动画。

属性:

然后对有子 View 的 ViewGroup 添加这个属性,比如 RecyclerView:

<android.support.v7.widget.RecyclerView
    android:id="@+id/recycler"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layoutAnimation="@anim/layout_anim" />

代码方式

其中子元素所用的补间动画代码方式前面已经说过,这里就直接用 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:其他视图的消失导致某个视图改变
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:id="@+id/rootView"
    android:animateLayoutChanges="true">
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:id="@+id/btnAdd"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAllCaps="false"
            android:text="addView" />
        <Button
            android:id="@+id/btnRemove"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAllCaps="false"
            android:text="removeView" />
    </LinearLayout>
</LinearLayout>
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)
}

效果:

2018_03_31_18_13_43.gif
上一篇 下一篇

猜你喜欢

热点阅读