概述
在Android中,属性动画系统是一个强健的框架,几乎允许你让一切东西动起来。你可以定义一个动画,随着时间的改变来改变任何一个对象的属性的值,不用去管它是否绘制在屏幕上。一个属性动画可以在一个指定的时间长度内改变一个属性的值。为了让一些东西动起来,你需要指定好对象的属性(例如一个对象在屏幕上的位置),你想让它运动多久和你想让它在什么值区间运动。
在Android属性动画系统中,我们可以为一个动画定义以下一些特性:
持续时间:你可以为一个动画指定持续时间。默认的持续时间是300ms.
时间插补:你可以根据动画目前的运行时间来指定属性的值如何计算
重复次数和行为:你可以指定一个动画完成后是否重复和重复的次数。你也可以指定动画反着运动,并且重复次数完成为止
动画集:你可以把一些动画组成一个含逻辑的集合,一起或顺序或指定延迟后运动
帧率:你可以指定一个动画帧率。默认是每10ms一帧,但是在你的应用中动画播放的帧率是依赖于系统的整体繁忙程度和系统底层的计时器服务情况
属性动画的工作原理
首先让我们来看一个简单的示例动画,图1描绘了一个以x属性运动的假想对象,x属性代表了它在屏幕上水平方向上的位置。这个x属性动画的持续时间是40ms,要完成的距离是40像素。每一帧刷新的频率是10ms,每切换一帧移动10像素。40ms过后,动画停止,运动的对象就在水平方向40像素的地方。这是一个线性插值的动画,这意味着对象以一个恒定的速度移动。
![](http://developer.android.com/images/animation/animation-linear.png)
Figure 1.
Example of a linear animation
在Android属性动画系统中,你也可以指定一个不是线性插值的动画。图2就示例了一个假想的对象,前半部分进行加速运动,在动画的后半部分进行减速运动。但依然是用40ms移动了40像素,显然不是线性匀速的。在开始和末尾单位时间内移动的都很慢,但在中间部分却移动的很快。
![](http://developer.android.com/images/animation/animation-nonlinear.png)
Figure 2. Example of a non-linear animation
现在就让我们来详细的了解下Android的属性动画系统计算动画的重要组成部分。图3描述了主要的类之间的合作关系
![](http://developer.android.com/images/animation/valueanimator.png)
Figure 3. How animations are calculated
ValueAnimator 会跟踪动画的过程,例如它知道动画播放多久了,还有属性每一时刻的值。
ValueAnimator 在内部封装了一个
TimeInterpolator
,
TimeInterpolator
定义了动画的插值,并且还封装了一个
TypeEvaluator ,
TypeEvaluator 定义了动画播放过程中怎么去计算属性的值。例如,在图2中,
TimeInterpolator 用的可能是
AccelerateDecelerateInterpolator
,
TypeEvaluator 用的可能是
IntEvaluator
为了开始一个动画,你需要创建一个
ValueAnimator 并且为你需要运动的属性设置起始和结束值和动画持续的时间。当你调用
start()
时,意味着动画开始了。在动画的整个过程中,
ValueAnimator
会实时计算一个完成分数,取值为0到1,这个计算依赖于动画持续的时间和已经运动的时间。完成分数代表了动画运动了多长时间。例如,在图1中(注意是匀速),在t=10ms处完成分数就是0.25,因为持续时间是t=40ms
当
ValueAnimator
计算好完成分数后,就会去调用目前设置的
TimeInterpolator
来计算一个插值分数。一个插值分数在充分考虑设置的时间插值下会把完成分数映射到一个新的分数。例如,在图2中(非匀速),因为动画在慢慢的加速,在t=10ms处,插值分数为0.15(6/40),小于完成分数0.25。在图1中,插值分数和完成分数一直都是相等的。
当插值分数计算完成后,
ValueAnimator 会去调用适当的
TypeEvaluator 来计算属性的值,基于插值分数,开始值和动画结束时候的值。例如,在图2中,在t=10ms处插值分数为0.15,所以在t=10ms处属性的值为 0(startPos)+0.15 * (40 - 0) = 6
在
API Demos中,
com.example.android.apis.animation
包为我们介绍了如何来使用Android的属性动画系统。
属性动画和视图动画的区别
视图动画系统只为我们提供了视图动画的能力,所以如果你想动画非视图对象,你只有自己编写代码来实现了。视图动画局限于一些实际情况,视图只有一些方面能用于进行动画,比如缩放和旋转,但背景颜色不行。
视图动画的另外一个缺点是只有绘制在屏幕上的视图才能够进行动画,并且不是视图本身。例如,如果你想让一个button在屏幕移动,移动后button是能够在正确的坐标上绘制,但是实际在屏幕上你能点击的地方(还在移动之前的位置)并没有发生变化,所以你需要实现自己的逻辑来处理这种情况。
在属性动画系统中,这些限制是完全不存在的,你可以动画任何对象的任何属性,并且对象本身也会被修改。属性动画能以更强健的方式进行。在一个高版本中,你可以为你想要修改的几个属性都指定动画器,例如颜色啊,位置啊,或者大小,一块儿改变,并且能够同时定义动画的几个方面,例如插值和同步多个动画器
但是视图动画系统也有一些优点,如花费更少的时间来设置和编写更少的代码就能实现。如果视图动画能完成任何一件你希望做的事,或者如果你的现有的代码已经按你所希望的方式工作了,那么就没有必要去使用属性动画系统。有的时候也有意义同时使用两种动画系统,如果出现这样的用例的话