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

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 是一个普通的补间动画。

属性:

  • 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:

<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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏向治洪

android顶部导航条

  今天给大家介绍在Android中实现顶部导航菜单左右滑动效果的二种解决方案。   第一种解决方案:    在以前的一篇博文中我使用android-su...

94950
来自专栏Android干货

浅谈FloatingActionButton(悬浮按钮)

77890
来自专栏zcqshine's blog

ajaxFileUpload+ThinkPHP+jqGrid 图片上传与显示

43840
来自专栏Android干货

浅谈ClickableSpan , 实现TextView文本某一部分文字的点击响应

15240
来自专栏计算机编程

Kotlin 自定义 标签viewgroup

一般在java语言中,constructor直接在继承viewgroup后会报错,然后根据自定义快捷键,默认为alt+enter【博主是用的eclipse 的k...

15430
来自专栏Android知识点总结

Android关于Canvas你所知道的和不知道的一切

Picture相当于先拍一张照片,并且是在别的Canvas上,在别的Canvas上,在别的Canvas上! 重要的话说三遍:当需要的时候在贴在当前的canva...

60020
来自专栏分享达人秀

Android用户界面开发概述

相信通过前面15期的学习,Android的开发环境已经基本掌握了,如果仍有问题,欢迎到Android零基础入门技术讨论微信群交流,从本期开始正式来一步一...

265100
来自专栏Android-薛之涛

Android-Animation 总结(一)

鉴于今天是劳动节,鼓励自己整理一下android相关的知识,祝所有劳动者节日快乐。

10210
来自专栏李蔚蓬的专栏

3.6 自定义View (3.6.1)

Android给我们提供了丰富的组件库来创建丰富的UI效果,同时也提供了非常方便的拓展方法。通过继承Android的系统组件,我们可以非常方便地拓展现有功能,在...

10520
来自专栏Android-薛之涛

Android-Animation 总结(二(Valueanimator))

          之前讲了帧动画和补间动画,今天我们来说一说重头戏---Android Animation之属性动画(property animation)。

7910

扫码关注云+社区

领取腾讯云代金券