Android动画(六):布局动画

Catalogue
  1. 1 LayoutAnimation
  2. 2 LayoutTransition
  3. 3 总结
  4. 参考资料

笔者已将本节的代码上传至 Github,大家可以结合着学习。
在 Android 的动画体系中,有补间动画,帧动画和属性动画,但是这些动画都是针对单个对象的,如果想对 ViewGroup 作动画,就要用到布局动画了。布局动画一共有两种:LayoutAnimation 和 LayoutTransition,本文将逐一介绍他们的用法和区别。

1 LayoutAnimation

LayoutAnimation 布局动画属于补间动画的一种,利用它可以快速实现对 ViewGroup 中子 view 的动画。不过,它的缺陷是只能够在 ViewGroup 初始化时对其子 view 产生动画效果,之后再增加子 view 时没有效果。
LayoutAnimation 动画可以直接在 xml 中定义:
1、首先定义单个 View 的补间动画

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500">
<translate
android:fromXDelta="-50%p"
android:toXDelta="0"/>
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"/>
</set>

2、定义 layoutAnimation

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:animation="@anim/slide_in_from_left"
android:animationOrder="random"
android:delay="1"/>
<!--
1、delay : ViewGroup 中单个Item动画的开始延时,取值是android:animation 所指定动画时长的倍数,可以是float,也可以是百分数,默认0.5
比如slide_in_from_left中定义的动画时长是500ms,这里delay=1,那么在上一个动画执行之后延时500ms执行下一个item的动画
2、animationOrder : 动画开始顺序,normal(正序)、reverse(倒序)、random(随机)
3、animation : 指定动画资源animation,注意不能使用animator
-->

可以通过下面两种方式加载
1、直接在 ViewGroup 的 layout xml 文件中设置:

1
android:layoutAnimation="@anim/list_item_slide_layout_animation"

2、使用代码设置:

1
2
3
4
5
6
Animation animation = AnimationUtils.loadAnimation(mActivity,R.anim.slide_in_from_left);
LayoutAnimationController animationController = new LayoutAnimationController(animation,
1f);
animationController.setOrder(LayoutAnimationController.ORDER_NORMAL);
mList.setLayoutAnimation(animationController);
mList.startLayoutAnimation();

同时,系统也提供了 gridLayoutAnimation 用于给 Gridview 设置布局动画。
需要注意的是布局动画,在创建ViewGroup的时候生效,后续添加的子View是没有动画效果的。

2 LayoutTransition

LayoutTransition 是API Level 11 才出现的。LayoutTransition 的动画效果,只有当 ViewGroup 中有 View 添加、删除、隐藏、显示的时候才会体现出来,初始化时没有效果。
LayoutTransition 类中主要有五种容器转换动画类型,具体如下:

LayoutTransition.APPEARING:子 View 添加到容器中时的过渡动画效果。
LayoutTransition.CHANGE_APPEARING:子 View 添加到容器中时,其他子 View 位置改变的过渡动画。
LayoutTransition.DISAPPEARING:子 View 从容器中移除时的过渡动画效果。
LayoutTransition.CHANGE_DISAPPEARING:子 View 从容器中移除时,其它子 View 位置改变的过渡动画。
LayoutTransition.CHANGING:子 View 在容器中位置改变时的过渡动画,不涉及删除或者添加操作。(没有试出效果,哪位大神知道用法的话,欢迎到github留个言,谢谢。)

LayoutTransition 也有两种方式添加。
1、在xml中直接添加。

1
2
// 只能使用系统默认的 LayoutTransition 动画
android:animateLayoutChanges="true"

2、在代码中使用。
使用系统默认的 LayoutTransition 动画

1
2
LayoutTransition mTransitioner = new LayoutTransition();
mViewGroup.setLayoutTransition(mTransitioner);

注意:使用系统动画时,会出现动画未达到预期的现象。此时应该从这些方面考虑:
a. 直接子 View 是一个容器,且容器中的子 View 是否过多?
b. 直接子 View 之间的依赖关系是否能达到动画预期?
c. 运用在 SurfaceView 上的动画效果会异常。

使用自定义的 LayoutTransition 动画

1
2
3
4
5
LayoutTransition layoutTransition = new LayoutTransition();
viewGroup.setLayoutTransition(layoutTransition);
...
layoutTransition.setAnimator(transitionType, AnimatorInflater.loadAnimator(this, R.animator.xxx));
<!--transitionType代表五种容器转换动画类型; R.animator.xxx代表属性动画资源。-->

同时,可以给 LayoutTransition 设置监听器

1
mTransitioner.addTransitionListener(new LayoutTransition.TransitionListener(){//...}

3 总结

布局动画类 类型 优缺点 发布版本
LayoutAnimation 补间动画 优点:快速实现对 ViewGroup 中子 View 的动画。对于 RecyclerView 这些 list 类型的 ViewGroup 同样适用。
缺点:只能够在 ViewGroup 初始化时对其子 View 产生动画效果。
API Level 1
LayoutTransition 属性动画 优点:ViewGroup 中只要有子 View 添加、删除、隐藏、显示,都能对子 View 的产生动画。。
缺点:1、对于 RecyclerView 不适用,我在实验滑动的时候是直接报错了,所以我建议如果是 RecyclerView 的话,还是用它自带的 ItemAnimator。2、对于 ListView 适用,参考这个链接,不过效果有点乱,同时还使得问题复杂化了,我在stackoverflow上看到了这个问题的回答。3、初始化 ViewGroup 时没有效果。
API Level 11

参考资料

1.Android 动画(一) LayoutAnimation 与 LayoutTransition
2.Android animation 30天上手 — Day13 LayoutTransition