您的位置:首页 > 运维架构

Property Animation(属性动画)

2016-07-12 10:06 176 查看


概述

属性动画系统是一个强大的框架,它允许你将大多数东西动画化。你可以定义一个动画用来在动画播放的时候改变任何对象的属性值,而不管它在屏幕上有没有被绘制。属性动画在指定长度的时间内改变一个属性(对象的一个字段)的值。开始动画化一些东西,由你指定你想要动画化的对象属性,如一个在屏幕上的对象的属性,指定动画播放的时长,和在动画时改变成什么值。

属性动画系统会指导你如何去定义一个动画,只需要遵循如下步骤:

持续时间:可以指定动画的持续时间,默认是300ms

时间插值:可以在动画运行时通过一个函数来指定需要改变的属性值多久计算一次。

重复次数和行为:当动画播放到末尾时,可以指定是否重复播放以及播放的次数。你还可以指定动画是否倒着播放。设置反向播放动画反复向前然后向后,直到达到重复出现的次数。

动画设置:可以对动画进行逻辑分组,一起播放或顺序播放或指定延迟播放。

帧刷新延迟:可以指定动画帧的刷新频率。默认值是每10ms刷新一次,但是最终的刷新速度取决于你系统整体的繁忙度和响应时间。


属性动画工作原理

首先,让我们通过一个简单的例子来了解动画是如何工作的。图1描述了一个假设的对象对它的x属性进行动画化,即它在屏幕上的水平位置。动画的持续时间设置为40ms并且x增大了40像素。每10ms,即默认帧刷新时间,该对象的水平距离就移动10像素。到最后的40ms时,动画停止,此时该对象的水平距离是40。这就是一个带有线性插值的动画,意味着该对象以一个恒定速度移动了。



图1.线性动画示例

你也可以将它设置为非线性的。图2说明了一个假想的对象在动画的前一段时间内加速,后一段时间内减速的动画效果。该对象依旧是在40ms中移动了40像素,但并非线性的。开始的一段时间,该动画加速至一半的点(即X=20),然后从这点开始减速,直到最后。如图2所示,开始和结束时移动的距离小于中间。



图2.非线性动画示例

让我们详细的看看属性动画系统的重要组件是如何像上面一样计算动画的。图3描述了主要的类是如何与其他类工作的。



图3.动画是如何计算的

ValueAnimator
对象在动画期间持续跟踪,如动画已经运行了多长时间,和当前动画的属性值。

ValueAnimator
封装了一个TimeInterpolator,被用来定义补间动画,还有一个
TypeEvaluator
,被用来定义动画开始后的属性值。例如,在图2,
TimeInterpolator
将会使用
AccelerateDecelerateInterpolator
,而
TypeEvaluator
将会使用
IntEvaluator
.。

开始一个动画,创建一个
ValueAnimator

并且给它你想要动画化属性开始和结束的值,随着动画的进行。当调用start(),动画开始播放。在动画播放的整个时间段内,
ValueAnimator
计算一个在0和1之间的已播放分数(elapsed
fraction),基于持续时间和已播放时间。这个已播放分数代表着动画播放完成时间的百分百,0意味着0%,1意味着100%。例如,在图1,在t=10ms时的已播放分数是0.25因为总的持续时间是40ms。

ValueAnimator
计算完成了一个已播放分数,就会调用刚才设置的
TimeInterpolator
来计算插值分数(interpolated
fraction)。一个插值分数将已播放分数映射到一个新的需要考虑时间插值的分数。例如,图2中,因为动画是逐渐加速的,在t=10ms时,它的插值分数,大约是0.15,小于此时的已播放分数0.15。在图1,插值分数永远等于已播放分数。

当插值分数计算完成,
ValueAnimator
调用适当的
TypeEvaluator
,来计算你需要动画化的属性的值,基于插值分数,开始值和结束值。例如,在图2中,t
=10ms时的插值分数是0.15,所以此时的属性值将会是0.15x(40-0),或者6。

com.example.android.apis.animation
包下的API
Demos有许多关于如何使用属性动画系统的例子。


属性动画与视图动画的不同之处

视图动画系统仅仅提供了动画化view对象的能力,因此如果你想要动画化非view对象,只能由你自己去编码实现了。视图动画系统也是受限制的,因为它只公开了几个方面的动画视图对象,如对view的缩放和旋转,而没有背景颜色。

视图动画的另一个缺点是它只在View绘制时修改视图,并非真正修改view本身。例如,如果你实现一个让一个按钮从左至右穿过屏幕这样的一个动画,按钮会正确的绘制,但是它的实际位置是没有变化的,你还是可以在原来的位置点击它,所有你必须实现自己的逻辑来处理这个问题。

而属性动画系统,这些约束完全被移除了,并且你可以动画化任何对象(view和非view)的任何属性,对象本身也确实被修改了。属性动画系统也用更健壮的方式执行动画。在更高层次上,你可以为你想要动画化的属性,如颜色,位置,或大小,分配动画师,并且可以定义动画的各个方面,如插值和多个画师同步。

视图动画系统,然而,花费更少的时间来设置,需要更少的代码编写。如果视图动画完成了你需要做的一切,或者如果你现有的代码已经按你所期望的方式工作了,那就不需要使用属性动画系统了。如果用例出现了不同的情况,使用动画系统也是十分有意义的。


API概述

android.animation
.中可以找到最多的关于属性动画系统的API相关知识。因为在
android.view.animation
中已经定义了许多视图动画系统的插入器,你可以在属性动画系统中使用这些插入器。接下来的几张表格展示了属性动画系统的主要组件。

Animator类提供了创建动画的基础结构。一般情况下你不必直接使用该类,它仅提供最小的功能,因此你必须继承它用以完全支持动画值。下面的这些子类都继承自Animator

Table1.Animators
ClassDescription
ValueAnimator
属性动画的主要计时引擎,也经常计算动画时的属性值。它具有所有的核心功能——计算动画值和包含每个动画的时间细节,有关于动画何时重复播放的信息,接收更新事件的监听器,设置自定义的估计(evaluate)类型.它主要有两个功能:计算动画的值和在动画时为对象设置这些值。
ValueAnimator
并不执行第二个功能,
因此你必须通过监听.
ValueAnimator
计算出来的值的更新事件
来用你自己的逻辑修改你想要动画的对象的值。查看#使用ValueAnimator制作动画部分获取更多消息。

ObjectAnimator
ValueAnimator
的一个子类,允许你设置目标对象和需要动画化的属性。
该类根据动画计算出来的新值来更新属性值.大多数时候你需要用到
ObjectAnimator
,
因为它使动画值用在目标对象上更加容易。然而,有些时候你必须直接使用
ValueAnimator
因为
ObjectAnimator
有一些限制,例如在目标对象上请求特定的存取方法。
AnimatorSet
提供一个组织动画的途径,这样你可以让它们通过一个顺序运行。例如一起播放,顺序播放,或延迟播放.查看#使用AnimatorSet编排复合动画章节获取更多信息。
求值器(Evaluator)告诉属性动画系统如何计算给定属性的值。它们通过
Animator
类来获取提供的时间数据,动画开始和结束的值,并且基于这些值计算动画时的属性值。属性动画系统支持如下求值器:

Table2.Evaluators
Class/InterfaceDescription
IntEvaluator
计算int属性的默认求值器
FloatEvaluator
计算float属性的默认求值器
ArgbEvaluator
计算颜色属性的默认求值器,是一个十六进制的值
TypeEvaluator
一个允许你创建自己的求值器的接口。如果你要计算的对象属性值不在int,float,或颜色之中,你必须实现
TypeEvaluator
接口来指定如何计算动画属性值。你也可以为int,float,color指定一个自定义的求值器,如果不你想用默认方法的处理这些类型。查看#使用TypeEvaluator章节获取更多信息
时间插值器(timeinterpolator)定义了一个时间函数如何在动画时计算一个特定的值。例如,你可以指定动画在整个动画时是线性发生的,意味着在整个时间内动画移动是匀速的。或者你可以指定为非线性的,例如在开始时加速,结束时减速。表3描述了包含在
android.view.animation
.中的插值器。如果这之中没有你需要的,实现TimeInterpolator接口来创建你自己的。查看#使用插值(Interpolators)来获取更多关于如何自定义插值器的知识。

Table3.Interpolators
Class/InterfaceDescription
AccelerateDecelerateInterpolator
开始和结束时慢,中间快
AccelerateInterpolator
开始慢,然后加速
AnticipateInterpolator
开始向后,然后向前
AnticipateOvershootInterpolator
开始向后,甩向前并且冲过目标值,最终回到目标值
BounceInterpolator
最后反弹
CycleInterpolator
重复指定次数
DecelerateInterpolator
开始快,然后减速
LinearInterpolator
恒定不变速度
OvershootInterpolator
甩向前,冲过目标值,然后回来
TimeInterpolator
可以让你实现自动的插值器的一个接口


使用ValueAnimator制作动画

ValueAnimator
类可以在动画持续时间内通过指定一组int,float
或color值实现某些动画类型。通过调用它的工厂方法来获得
ValueAnimator
ofInt()
,
ofFloat()
,
or
ofObject()
例如



ValueAnimatoranimation=ValueAnimator.ofFloat(0f,1f);
animation.setDuration(1000);
animation.start();
[/code]

代码中,当
start()方法开始运行时,
ValueAnimator
开始计算动画值,介于0和1之间,持续时间是1000ms

你还可以为动画指定一个自定义类型,如下:

ValueAnimatoranimation=ValueAnimator.ofObject(newMyTypeEvaluator(),startPropertyValue,endPropertyValue);
animation.setDuration(1000);
animation.start();
[/code]

代码中,当start()方法开始运行时,
ValueAnimator
开始计算动画值,介于
startPropertyValue
endPropertyValue
之间,使用由
MyTypeEvaluator
提供的逻辑,持续时间1000ms


上面的代码片段,是的,在一些对象上是没有有实际作用的,因为
ValueAnimator
并不直接操作对象或值。更有可能的方法是通过修改这些动画的计算值来修改对象。在
ValueAnimator
中定义一个监听器来处理动画期间的重要事件,如帧刷新。当实现了该监听器,你可以通过调用
getAnimatedValue()
.得到这一帧刷新时的计算值。更多关于这个监听器的知识,请看#动画监听器。


使用ObjectAnimator制作动画

ObjectAnimator
ValueAnimator
的子类(在之前章节介绍过)并且结合了时序引擎和计算ValueAnimator的目标对象动画化属性值的功能。这使得动画化任何对象变得容易,一如你不再需要实现
ValueAnimator.AnimatorUpdateListener,
因为它的动画属性会自动更新。

实例化一个
ObjectAnimator
对象和实例化ValueAnimator相似,但是你依然要指定对象和对象属性的名称(作为String
)和两个动画值:

ObjectAnimatoranim=ObjectAnimator.ofFloat(foo,"alpha",0f,1f);
anim.setDuration(1000);
anim.start();
[/code]

为了让
ObjectAnimator
正确的更新,你必须做如下工作:

○需要动画的对象属性必须要有函数形式为set<propertyName>()的setter函数。因为
ObjectAnimator
在动画时自动的更新属性,一定要通过这个setter函数来设置属性。例如,如果这个属性名为
foo
,你就必须要有一个setFoo()的方法。如果没有这样的setter
方法,你有三种选择:

如果你有权利这么做,在类中加入这个setter方法。

使用包装类,这样你就有权去更改这个包装类,并且该包装类通过setter函数获得有效的值,并将它转发给原来的对象。

使用
ValueAnimator
替代

○如果在
ObjectAnimator
的某一构造函数中,你的
values...
参数中只有一个值,它将被假定为结束值。因此,动画对象的属性必须有一个getter函数用来获得动画开始时的开始值。这个getter函数必须是get<propertyName>()形式的。例如,如果属性名为foo,你必须有一个getFoo()的函数。

○动画属性的getter
函数(如果需要)和setter函数必须操作的是同一类型的由
ObjectAnimator
指定的开始和结束值。例如,如果你构造了如下的
ObjectAnimator
:,你必须有
targetObject.setPropName(float)
targetObject.getPropName(float):


ObjectAnimator.ofFloat(targetObject,"propName",1f)
[/code]

取决于你的动画属性和对象,当view显示在屏幕上时,你或许需要调用invalidate()方法来重绘视图和更新动画值。在onAnimationUpdate()回调函数中做这些事情。例如,为一个可绘制对象的颜色属性做动画,当这个对象重绘自己的时候才导致更新屏幕。所有view
上的设置,如
setAlpha()
setTranslationX()
直接无效了,所以当调用这些方法设置新值时,你不必无效化view。更多关于监听器的信息,请查看#动画监听器


使用AnimatorSet编排复合动画

在许多情况下,你想要播放的动画取决于其它的动画开始或结束后。安卓系统使你可以在AnimatorSet中将动画整合在一起,这样你就可以指定是否同时播放动画,顺序播放,或者延迟指定时间后播放。你也可以彼此嵌套(nest
)
AnimatorSet
对象。

接下来的示例代码取自Bouncing
Balls示例(简单的修改了)通过如下的方式播放了如下的
Animator
对象:

Plays
bounceAnim
.
Plays
squashAnim1
,
squashAnim2
,
stretchAnim1
,
and
stretchAnim2
同时播放
Plays
bounceBackAnim
.
Plays
fadeAnim
.

AnimatorSetbouncer=newAnimatorSet();
bouncer.play(bounceAnim).before(squashAnim1);
bouncer.play(squashAnim1).with(squashAnim2);
bouncer.play(squashAnim1).with(stretchAnim1);
bouncer.play(squashAnim1).with(stretchAnim2);
bouncer.play(bounceBackAnim).after(stretchAnim2);
ValueAnimatorfadeAnim=ObjectAnimator.ofFloat(newBall,"alpha",1f,0f);
fadeAnim.setDuration(250);
AnimatorSetanimatorSet=newAnimatorSet();
animatorSet.play(bouncer).before(fadeAnim);
animatorSet.start();
[/code]

更多关于如何使用动画集合的完整示例,请看API示例中的Bouncing
Balls实例。


动画监听器

在动画持续时间内,你可以监听如下重要的事件。

Animator.AnimatorListener


onAnimationStart()
-
动画开始是调用
onAnimationEnd()
-
动画结束时调用
onAnimationRepeat()
-
动画重复播放时调用
onAnimationCancel()
-
动画取消时调用.取消动画也会调用
onAnimationEnd()
,
无论该动画是否已经播放完成。

ValueAnimator.AnimatorUpdateListener


onAnimationUpdate()
-
动画的每一帧时调用.在动画期间,通过监听该事件来使用由ValueAnimator产生的计算值。使用这一值,询问传递到该事件中的
ValueAnimator
对象,通过
getAnimatedValue()
来获取当前动画值。如果你使用了
ValueAnimator
就需要实现这一监听器。
取决于你的动画属性和对象,当view显示在屏幕上时,你或许需要调用invalidate()方法来重绘视图和更新动画值。在onAnimationUpdate()回调函数中做这些事情。例如,为一个可绘制对象的颜色属性做动画,当这个对象重绘自己的时候才导致更新屏幕。所有view上的设置,如setAlpha()和setTranslationX()直接无效了,所以当调用这些方法设置新值时,你不必无效化view。

你可以继承
AnimatorListenerAdapter
类而不是实现Animator.AnimatorListener接口,如果你不想实现Animator.AnimatorListener接口中的所有方法。
AnimatorListenerAdapter
类提供了空的实现方法供你选择性的覆盖。

例如,在api示例中的BouncingBalls案例中,创建了一个AnimatorListenerAdapter,仅仅只是调用了
onAnimationEnd()


ValueAnimatorAnimatorfadeAnim=ObjectAnimator.ofFloat(newBall,"alpha",1f,0f);
fadeAnim.setDuration(250);
fadeAnim.addListener(newAnimatorListenerAdapter(){
publicvoidonAnimationEnd(Animatoranimation){
balls.remove(((ObjectAnimator)animation).getTarget());
}
[/code]




为ViewGroups做布局改变动画

属性动画系统提供了对ViewGroup对象动画化的能力,使得像动画化View一样简单。

通过使用LayoutTransition类你可以做一个布局改变时的动画。在ViewGroup中的View可以播放出现和消失动画,当你将它们添加或移除ViewGroup时,或者调用View的
setVisibility()
方法设置时。当你添加或移除View时,ViewGroup中其余的View也可以动画移动到新的位置。通过调用
LayoutTransition
setAnimator()
传递一个
Animator
对象和如下的一个
LayoutTransition
常量,来定义一个动画:

APPEARING
-一个标志,表明那些出现在容器中的项目的动画。
CHANGE_APPEARING
-表明那些由于新项目出现在容器中而需要改变的项目的动画
DISAPPEARING
-表明那些从容器中消失的项目的动画
CHANGE_DISAPPEARING
-表明那些由于一个项目在容器中消失而需要改变的项目的动画,

你可以定义你自己的动画效果,由这四个类型的事件来定制你的布局过渡效果,或者直接告诉动画系统使用默认动画。

在api样例中的LayoutAnimations示例展示了如如何自定义一个布局过渡动画,然后在你想要动画化的View对象上使用它。

LayoutAnimationsByDefault和相应的layout_animations_by_default.xml布局资源文件展示了如何在xml文件中启用默认的布局过渡。你需要做的唯一事情就是设置ViewGroup中的
android:animateLayoutchanges
属性为
true
,如下:

<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="@+id/verticalContainer"
android:animateLayoutChanges="true"/>
[/code]

设置这个属性为真,会自动的动画视图,当从这个ViewGroup中添加或移除视图时。添加/移除的项和剩下的项都有动画效果。


使用TypeEvaluator

如果你想要动画化的类型在安卓系统中未知,你可以通过实现
TypeEvaluator
接口来创建自己的求值器。目前安卓系统可识别的类型是int,float
或一个颜色值,分别对应
IntEvaluator
,
FloatEvaluator
,
ArgbEvaluator
的类型求值器。
TypeEvaluator
接口中只有一个需要实现的方法,evaluate()方法。它允许动画师使用一个
在动画的确切时间点返回的适当的动画属性值。
FloatEvaluator
类演示了如何做:

publicclassFloatEvaluatorimplementsTypeEvaluator{
publicObjectevaluate(floatfraction,ObjectstartValue,ObjectendValue){
floatstartFloat=((Number)startValue).floatValue();
returnstartFloat+fraction*(((Number)endValue).floatValue()-startFloat);
}
}
[/code]

注:当
ValueAnimator
(or
ObjectAnimator
)运行时,为动画计算了一个确切的已运行分数(介于0-1之间的值),然后计算了一个插值,具体取决于你所使用的插值器。插值分数是你的TypeEvaluator通过
fraction
参数收到的,所有在计算动画值时不需要考虑插值器。


使用插值(Interpolators)

一个插值定义了如何在动画时计算具体值的一个时间函数。例如,你可以指定动画在播放时是线性的,意味着动画在整个播放时间内是匀速运动的,或者可以指定为非线性的,例如在开始时加速,结束时减速。

动画系统中的插值器接收一个由动画师发来的分数,这个分数代表着动画已经播放的时间。插值器修改这个分数用以与提供的目标动画类型相一致。在
android.view.animation
package
.包下安卓系统提供了一组通用的插值器。如果这些都不适合你,可以实现
TimeInterpolator
接口来创建自己的插值器。

举个例子,比较默认的插值器
AccelerateDecelerateInterpolator
LinearInterpolator
是如何计算插值分数的。
LinearInterpolator
对已播放分数没有影响。AccelerateDecelerateInterpolator加速进入动画,减速出来。下面展示了他们的插值逻辑:

AccelerateDecelerateInterpolator

publicfloatgetInterpolation(floatinput){
return(float)(Math.cos((input+1)*Math.PI)/2.0f)+0.5f;
}
[/code]

LinearInterpolator

publicfloatgetInterpolation(floatinput){
returninput;
}
[/code]

下表展示了由这些插值器计算一个时长为1000ms的动画的近似值:

已播放

ms
已播放分数/插值分数

(Linear)
插值分数

(Accelerate/Decelerate)
000
200.2.1
400.4.345
600.6.8
800.8.9
100011
如表所示,
LinearInterpolator
以恒定速度改变值,每过200ms增长.2。
AccelerateDecelerateInterpolator
LinearInterpolator
改变值的速度,在200ms
-600ms的时候更快,在600ms-1000ms的时候更慢。


指定关键帧

关键帧对象由一个时间/值对组成,是由你指定的动画中的一个特定时间的状态。每一个关键帧都有自己的插值器来控制他们的动画行为,在前一个关键帧和这一个关键帧之间。

实例化一个
Keyframe
对象,你必须yonder其中的一个工厂方法,
ofInt()
,
ofFloat()
,
ofObject()
来获得合适类型的
Keyframe。之后调用
ofKeyframe()
工厂方法来获得一个
PropertyValuesHolder
对象。一旦你有了该对象,你可以通过传递
该对象和目标动画对象来获得一个动画制作者对象。像这样:

Keyframekf0=Keyframe.ofFloat(0f,0f);
Keyframekf1=Keyframe.ofFloat(.5f,360f);
Keyframekf2=Keyframe.ofFloat(1f,0f);
PropertyValuesHolderpvhRotation=PropertyValuesHolder.ofKeyframe("rotation",kf0,kf1,kf2);
ObjectAnimatorrotationAnim=ObjectAnimator.ofPropertyValuesHolder(target,pvhRotation)
rotationAnim.setDuration(5000ms);
[/code]

更多关于如何使用关键帧的完整示例,请看API案例中的MultiPropertyAnimation示例。


视图动画化

属性动画系统允许查看对象的流线型动画,并且在视图动画系统上提供了一些优势。视图动画系统通过改变它绘制的方式来变换view对象。由各个view容器处理,因为view本身没有属性可用来操作。这导致view可以被动画化,但是view本身不会有变化。这样就会有一个对象仍然在原来的位置的现象,尽管它被绘制在了屏幕的不同位置。在安卓3.0,新的属性和相应的getter
&setter方法被加入了,用以消除这一弊端。

属性动画系统可以通过改变view对象的实际值而在屏幕上动画化view。另外,当它的属性被改变时,views经常自动的调用
invalidate()
方法来刷新屏幕。在View
类中新添加的属性如下:

translationX
and
translationY
:
这些属性控制了View的位置,作为它左部和上部坐标的增量,由布局容器设置。平移
rotation
,
rotationX
,
and
rotationY
:这些属性控制了在2D和3D坐标系中围绕着中心点(锚点)的旋转。旋转
scaleX
and
scaleY
:这些属性控制了在2d坐标系中围绕着中心点(锚点)的缩放。缩放
pivotX
and
pivotY
:
这些属性控制了中心点的位置,它与旋转和缩放转换有关。默认情况下,中心点位于对象的正中央。锚点
x
and
y
:
用来描述view在容器中的最终坐标,是左部和上部加上x和y的偏移量的和。
alpha
:代表着view的透明度变化。默认值为1(不透明),越接近0代表着越透明(看不见)。

动画化一个view对象的属性,如它的颜色或旋转值,你只需要做的就是创建一个属性动画师,并且指定你想要动画化的属性。如:

ObjectAnimator.ofFloat(myView,"rotation",0f,360f);
[/code]

更多关于如何创建动画师的信息,看上文的#使用ValueAnimator制作动画和#使用ObjectAnimator制作动画


使用ViewPropertyAnimator制作动画

ViewPropertyAnimator
提供了一个简单的方法来并行动画化几个视图属性,使用一个简单的底层
Animator
对象。它的行为更像是
ObjectAnimator
,因为它修改了view的真实属性值,但是更加高效的是它同时动画化许多属性。另外,关于使用ViewPropertyAnimator的代码更加简洁和易于阅读。接下来的代码片段展示了复合ObjectAnimator对象,单一的
ObjectAnimator
,和
ViewPropertyAnimator
在同时动画化x和y属性时的不同。

MultipleObjectAnimatorobjects

ObjectAnimatoranimX=ObjectAnimator.ofFloat(myView,"x",50f);
ObjectAnimatoranimY=ObjectAnimator.ofFloat(myView,"y",100f);
AnimatorSetanimSetXY=newAnimatorSet();
animSetXY.playTogether(animX,animY);
animSetXY.start();
[/code]

OneObjectAnimator

PropertyValuesHolderpvhX=PropertyValuesHolder.ofFloat("x",50f);
PropertyValuesHolderpvhY=PropertyValuesHolder.ofFloat("y",100f);
ObjectAnimator.ofPropertyValuesHolder(myView,pvhX,pvyY).start();
[/code]

ViewPropertyAnimator

myView.animate().x(50f).y(100f);
[/code]

更多关于
ViewPropertyAnimator
,的详细信息,请看相应的安卓开发博文blog
post.


在XML文件中声明动画

属性动画系统允许你在xml文件中什么属性动画,代替编程实现。在xml中定义你的动画,可以更加方便的复用你的动画且更加容易的对动画排序。
为了区分动画文件,使用了那些使用传统视图动画框架的新的属性动画API,始于安卓3.1,你可以在
res/animator/
目录(不是res/anim/)下保持你的属性动画xml文件。使用animator目录是可选的,但是如果你想使用ADT插件(ADT
11.0.0+)的视图编辑工具时,这是必须的。因为ADT只会查找在res/animator/目录下的属性动画文件。
下面是属性动画类对应的xml标签元素:

ValueAnimator
-
<animator>

ObjectAnimator
-
<objectAnimator>

AnimatorSet
-
<set>


following下面一个案例播放了两套顺序播放的动画对象,第一个对象通过嵌套设置两个动画对象一起播放:

<setandroid:ordering="sequentially">
<set>
<objectAnimator
android:propertyName="x"
android:duration="500"
android:valueTo="400"
android:valueType="intType"/>
<objectAnimator
android:propertyName="y"
android:duration="500"
android:valueTo="300"
android:valueType="intType"/>
</set>
<objectAnimator
android:propertyName="alpha"
android:duration="500"
android:valueTo="1f"/>
</set>
[/code]

运行这个动画,你必须在你代码的AnimatorSet对象中展开这个xml资源,然后为在动画开始之前为这里的所有动画设置目标对象。调用
setTarget()
来设置一个简单对象,为方便,目标会应用于所有AnimatorSet的子节点。代码如下:

AnimatorSetset=(AnimatorSet)AnimatorInflater.loadAnimator(myContext,
R.anim.property_animator);
set.setTarget(myObject);
set.start();
[/code]

更多关于xml语法定义属性动画的信息,请看Animation
Resources.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息