属性动画

属性动画系统是一个强大的框架,允许你动画几乎任何东西。 您可以定义动画来随时间更改任何对象属性,而不管它是否绘制到屏幕。 属性动画在指定的时间长度内更改属性(对象中的字段)值。 要为某个动画添加动画,请指定要动画化的对象属性,例如对象在屏幕上的位置,要为其设置动画的时间长度,以及要在其间动画的值。

属性动画系统允许您定义动画的以下特征:

  • 持续时间:您可以指定动画的持续时间。 默认长度为300 ms。
  • 时间插值:您可以指定属性的值如何作为动画的当前耗用时间的函数计算。
  • 重复计数和行为:您可以指定是否在达到持续时间结束时重复动画,以及重复动画的次数。 您还可以指定是否要反转播放动画。 将其设置为逆向播放动画,然后向后重复播放动画,直到达到重复次数。
  • 动画集:您可以将动画分组为一起播放或顺序播放或在指定延迟后播放的逻辑集。
  • 帧刷新延迟:您可以指定刷新动画帧的频率。 默认设置为每10毫秒刷新一次,但应用程序可以刷新帧的速度最终取决于系统整体的忙碌程度以及系统如何快速为底层定时器提供服务。

物理动画如何工作


首先,让我们通过一个简单的例子来了解动画的工作原理。 图1描绘了动画与一个假想对象x属性,它表示在屏幕上的其水平位置。 动画的持续时间设置为40 ms,行进距离为40像素。 每10毫秒(默认帧刷新率),对象水平移动10像素。 在40ms结束时,动画停止,对象在水平位置40处结束。这是具有线性插值的动画的示例,意味着对象以恒定速度移动。


属性动画_第1张图片
animation-linear.png

** 图1.一个线性动画实施例 **

您还可以指定动画以具有非线性插值。 图2示出了在动画开始时加速的假想对象,并且在动画结束时减速。 对象在40毫秒内仍然移动40个像素,但是非线性。 开始时,此动画加速到中间点,然后从中间点减速直到动画结束。 如图2所示,在动画的开始和结束处行进的距离小于中间。


属性动画_第2张图片
animation-nonlinear.png

** 图2的非线性动画实施例**

让我们详细看看属性动画系统的重要组件如何计算如上所示的动画。 图3描述了主类如何彼此工作。


属性动画_第3张图片
valueanimator.png

** 图3.如何动画计算 **

ValueAnimator对象跟踪动画的时机,如多久动画已经运行,而且它是动画的属性的当前值。

所述ValueAnimator封装TimeInterpolator,它定义动画插值,和一个TypeEvaluator,它定义了如何计算属性值被动画。 例如,在图2中, TimeInterpolator用于将AccelerateDecelerateInterpolatorTypeEvaluatorIntEvaluator

要启动动画,营造ValueAnimator,并给它一个你想要的动画,用动画的持续时间沿线物业的开始和结束的值。 当你调用start()的动画开始。 在整个动画时, ValueAnimator计算0和1之间经过的级分 ,基于该动画的持续时间和多少时间已过。 已过分数表示动画完成的时间百分比,0表示0%,1表示100%。 例如,在图1中,在t = 10ms时的经过分数将是0.25,因为总持续时间是t = 40ms。

ValueAnimator完成计算经过的分数时,它调用TimeInterpolator当前设置,来计算内插的分数 。 内插分数将经过分数映射到考虑所设置的时间内插的新分数。 例如,在图2中,由于动画缓慢加速,所以内插分数(约.15)小于在t = 10ms时所经过的分数(.25)。 在图1中,内插分数总是与经过分数相同。

当计算内插级分,ValueAnimator调用相应TypeEvaluator ,来计算要基于内插级分,起始值和动画的结束值动画,该属性的值。 例如,在图2中,内插分数在t = 10ms时为.15,因此此时的属性值为.15 X(40 - 0)或6。

com.example.android.apis.animation包中的API演示示例项目提供了有关如何使用属性动画系统的例子很多。

如何物体动画不同于视图动画


视图动画系统提供了唯一的动画功能View对象,所以,如果你想非动画View对象,你必须实现自己的代码来做到这一点。 视图动画系统也是制约的事实,它仅仅公开了的几个方面View对象进行动画,诸如视图的缩放和旋转,但不是背景颜色,例如。

视图动画系统的另一个缺点是它只是在绘制视图时修改,而不是实际的View本身。 例如,如果你动画一个按钮在屏幕上移动,该按钮绘制正确,但是你可以点击按钮的实际位置不会改变,所以你必须实现自己的逻辑来处理这个。

使用属性动画系统,这些约束被完全删除,您可以对任何对象(视图和非视图)的任何属性进行动画处理,对象本身实际上已被修改。 属性动画系统在执行动画的方式上也更加鲁棒。 在高级别,您为动画效果分配动画效果,如颜色,位置或大小,并可以定义动画的方面,如插值和多个动画的同步。

然而,视图动画系统需要较少的时间来设置,并且需要较少的代码写入。 如果视图动画完成你需要做的一切,或者如果你现有的代码已经按你想要的方式工作,没有必要使用属性动画系统。 如果用例出现,也可以使用两种动画系统来处理不同的情况。

API概述


你可以发现,大部分的属性动画系统API的android.animation 。 因为视图动画系统已经定义了许多插值android.view.animation ,你可以在属性动画系统使用的插值为好。 下表描述了属性动画系统的主要组件。

Animator类提供用于创建动画的基本结构。 通常不直接使用此类,因为它只提供必须扩展以完全支持动画值的最小功能。 下面的子类扩展Animator

** 表1 **. Animators

描述
ValueAnimator 属性动画的主要计时引擎,还计算要动画化的属性的值。 它具有计算动画值并包含每个动画的时间细节的所有核心功能,关于动画是否重复的信息,接收更新事件的侦听器以及设置要评估的自定义类型的能力。 动画属性有两个部分:计算动画值,并在要动画的对象和属性上设置这些值。 ValueAnimator不进行第二块,所以你一定要听的更新,通过计算值ValueAnimator和修改要与自己的逻辑进行动画处理的对象。 请参阅有关的章节与ValueAnimator动画以获取更多信息。
ObjectAnimator ValueAnimator的一个子类,允许您设置一个目标对象和对象属性的动画。 此类在为动画计算新值时相应地更新属性。 你想用ObjectAnimator大部分时间,因为它使目标动画值的过程对象容易得多。 不过,有时你想使用ValueAnimator直接因为ObjectAnimator有几个限制,比如需要特定acessor方法出现在目标对象上。
AnimatorSet 提供一种将动画分组在一起以使它们彼此相关运行的机制。 您可以将动画设置为一起播放,顺序播放或在指定的延迟后播放。 请参阅有关部分创建与动画设置多个动画的详细信息。

评估者告诉属性动画系统如何计算给定属性的值。 它们采取一个通过提供定时数据Animator类,动画的开始和结束值,并计算基于该数据的属性的动画值。 属性动画系统提供以下评估器:

表2. Evaluators

类/接口 描述
IntEvaluator 默认的评估计算值int的属性。
FloatEvaluator 默认的评估计算值float的属性。
ArgbEvaluator 默认的评估来计算被表示为十六进制值的颜色属性的值。
TypeEvaluator 一个允许您创建自己的求值程序的接口。 如果您设置动画的对象属性不是一个intfloat ,或颜色,你必须实现TypeEvaluator界面指定如何计算对象属性的动画值。 您还可以指定一个自定义TypeEvaluatorintfloat ,色值,以及,如果你想以不同的方式处理这些类型比默认的行为。 看到关于该部分使用TypeEvaluator有关如何编写自定义的评估程序的更多信息。

时间插值器定义动画中的具体值如何作为时间的函数计算。 例如,您可以指定动画在整个动画中线性发生,这意味着动画在整个时间均匀移动,或者您可以指定动画以使用非线性时间,例如,在开始时加速,在结束时减速动画。 表3描述了包含在插值android.view.animation 。 如果没有提供插值适合您的需求,实现了TimeInterpolator接口,并创建自己的。 请参阅使用插值有关如何编写自定义的内插的更多信息。

表3. Interpolators

类/接口 描述
AccelerateDecelerateInterpolator 一个插补器,其变化率开始和结束缓慢,但加速通过中间。
AccelerateInterpolator 一个插补器,其变化率开始缓慢然后加速。
AnticipateInterpolator 一个内插器,其变化开始向后然后向前。
AnticipateOvershootInterpolator 一个插值器,它的变化向后开始,向前翻转和超过目标值,然后最终返回到最终值。
BounceInterpolator 一个内插器,其变化在结束时反弹。
CycleInterpolator 内插器,其动画重复指定数量的周期。
DecelerateInterpolator 变化率快速开始然后减速的插补器。
LinearInterpolator 变化率恒定的插补器。
OvershootInterpolator 内插器的变化向前移动并超过最后一个值,然后返回。
TimeInterpolator 一个接口,允许您实现自己的插值器。

使用ValueAnimator进行动画


ValueAnimator类,可以通过指定一组动画某种类型为动画的持续时间值intfloat ,或颜色值的动画通过。 你获得ValueAnimator通过调用其工厂方法之一:ofInt() ofFloat()ofObject()例如:

ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
animation.setDuration(1000);
animation.start();

在这段代码中,ValueAnimator开始计算动画的值,0和1之间,为1000毫秒的持续时间,当start()方法运行。

您还可以通过执行以下操作,将自定义类型指定为动画:

ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);
animation.setDuration(1000);
animation.start();

在这段代码中, ValueAnimator开始计算动画值之间startPropertyValueendPropertyValue利用所提供的逻辑MyTypeEvaluator为1000毫秒的持续时间,当start()方法运行。

上面的代码片段,然而,有一个对象上没有真正的影响,因为ValueAnimator不上对象或属性直接操作。 您最想做的事情是使用这些计算值修改要设置动画的对象。 您可以通过定义在听众做ValueAnimator妥善处理动画的生命周期中的重要事件,如帧更新。 在实施监听器,你可以通过调用获得该特定帧刷新的计算值getAnimatedValue() 有关监听器的详细信息,请参阅节动画听众

使用ObjectAnimator进行动画


ObjectAnimator是的子类ValueAnimator(在上一节中讨论),并结合了定时引擎和值计算ValueAnimator与动画的目标对象的指定属性的能力。 这使得动画的任何对象要容易得多,因为你不再需要实现ValueAnimator.AnimatorUpdateListener,因为动画属性将自动更新。

实例化一个ObjectAnimator类似于ValueAnimator ,但你也有间动画的数值沿指定对象,该对象的属性的名称(作为String):

ObjectAnimator anim = ObjectAnimator.ofFloat(foo, "alpha", 0f, 1f);
anim.setDuration(1000);
anim.start();

ObjectAnimator正确更新属性,必须做到以下几点:

  • 你是在形式动画必须有一个setter函数(骆驼的情况下)的对象属性set() 由于ObjectAnimator自动更新动画过程中的财产,它必须能与此setter方法来访问属性。 例如,如果属性名为foo ,你需要有一个setFoo()方法。 如果此setter方法不存在,您有三个选项:

  • 如果您有权这样做,请将setter方法添加到类中。

  • 使用您有权更改的包装器类,并使包装器接收具有有效 * setter方法的值,并将其转发到原始对象。

  • 使用ValueAnimator代替。

  • 如果仅指定一个值values...在的一个参数ObjectAnimator工厂方法,它被认为是动画的结束值。 因此,您要动画的对象属性必须有一个getter函数,用于获取动画的起始值。 该getter函数必须在形式get()例如,如果属性名为foo ,你需要有一个getFoo()方法。

  • 您指定的吸气剂(如果需要),并且您必须动画上同一类型为出发经营的财产的setter方法和期末值ObjectAnimator。 例如,你必须有targetObject.setPropName(float)targetObject.getPropName(float) ,如果你构建以下ObjectAnimator

ObjectAnimator.ofFloat(targetObject, "propName", 1f)
  • 根据什么属性或对象的动画,你可能需要调用invalidate()上查看方法强制屏幕更新的动画值重绘自身。 你在做onAnimationUpdate()回调。 例如,对Drawable对象的颜色属性进行动画处理只会在该对象重绘本身时更新屏幕。 所有在查看属性制定者,如setAlpha()setTranslationX()正确无效视图,所以你不需要调用这些方法与新的值时无效视图。 有关监听器的详细信息,请参阅节动画听众

与使用AnimatorSet编写多个动画


在许多情况下,你想播放一个动画,取决于另一个动画开始或结束时。 Android系统可以让你捆绑在一起的动画到AnimatorSet,这样你可以指定是否同时启动动画,顺序,或在指定的延迟。 您还可以使用AnimatorSet内的每个其他对象。

取自下面的示例代码弹弹球样品(修改为简单起见)饰演以下Animator以下列方式对象:

  1. 播放bounceAnim
  2. squashAnim1squashAnim2stretchAnim1,和 stretchAnim2同时。
  3. 播放bounceBackAnim
  4. 播放fadeAnim
AnimatorSet bouncer = new AnimatorSet();
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);
ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(bouncer).before(fadeAnim);
animatorSet.start();

有关如何使用动画集的更完整的示例,请参见弹弹球在APIDemos样本。

动画监听器


您可以在动画持续时间期间使用下面描述的侦听器侦听重要事件。

  • Animator.AnimatorListener
  • onAnimationStart() - 动画启动时调用。
  • onAnimationEnd() - 当动画结束时调用。
  • onAnimationRepeat() - 当动画重演调用。
  • onAnimationCancel()-当动画被取消调用。取消的动画还呼吁onAnimationEnd(),无论他们是如何结束。
  • ValueAnimator.AnimatorUpdateListener
  • onAnimationUpdate()-称为动画的每一帧上。 听此事件使用所产生的计算值ValueAnimator动画中。 要使用该值,查询ValueAnimator传递到事件来获取与当前动画值对象getAnimatedValue()方法。 实现这个监听器,如果您使用需要ValueAnimator

根据什么属性或对象的动画,你可能需要调用invalidate()上查看迫使屏幕的该区域的新的动画值重绘自身。 例如,对Drawable对象的颜色属性进行动画处理只会在该对象重绘本身时更新屏幕。 所有在查看属性制定者,如setAlpha()setTranslationX()正确无效视图,所以你不需要调用这些方法与新的值时无效视图。

您可以扩展AnimatorListenerAdapter类,而不是实现Animator.AnimatorListener接口,如果你不希望实现所有的方法Animator.AnimatorListener 接口。本AnimatorListenerAdapter类提供的,你可以选择覆盖的方法空的实现。

例如,弹弹球的API演示示例创建一个AnimatorListenerAdapter只是在onAnimationEnd() 回调:

ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
fadeAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
    balls.remove(((ObjectAnimator)animation).getTarget());
}

动画对ViewGroup的布局更改


属性动画系统提供了对ViewGroup对象进行动画更改的功能,以及提供一种简单的方法来动画化View对象本身。

您可以使用一个内部的ViewGroup动画布局的变化LayoutTransition类。 一个内部的ViewGroup意见可以通过出现和消失的动画,当你把它们添加到或从一个ViewGroup删除它们,或当你调用一个视图的setVisibility()方法, VISIBLE,android.view.View#看不见},或GONE 。 当您添加或删除视图时,ViewGroup中的其余视图还可以动画到其新位置。 您可以定义在下面的动画LayoutTransition通过调用对象setAnimator()并传递一个Animator对象,执行下列操作之一LayoutTransition常量:

  • APPEARING - 一个标志,指示对那些出现在容器项目运行动画。
  • CHANGE_APPEARING - 由于出现在容器中的新项目的标记,指示对正在改变项目运行动画的标志。
  • DISAPPEARING -一个标志,指示对从容器中消失的项目运行动画。
  • CHANGE_DISAPPEARING - 一个标志,指示在正在改变的项目运行动画由于从容器消失的项目。

您可以为这四种类型的事件定义自己的自定义动画,以自定义布局转换的外观,或者只是告诉动画系统使用默认动画。

LayoutAnimations在API演示示例说明如何定义动画布局的转换,然后设置上要设置动画查看对象的动画。

LayoutAnimationsByDefault及其相应layout_animations_by_default.xml 布局资源文件说明如何启用默认布局转换为XML ViewGroups。你需要做的唯一的事情是将设置android:animateLayoutchanges 属性true为的ViewGroup。例如:


将此属性设置为true会自动为从ViewGroup中添加或删除的视图以及ViewGroup中的其余视图创建动画。

使用TypeEvaluator


如果你想动画一个类型是未知的Android系统,你可以通过实现创建自己的计算器TypeEvaluator界面。由Android系统已知的类型是intfloat,或者一个颜色,其是由支持IntEvaluatorFloatEvaluatorArgbEvaluator类型评估。

只有一个在执行方法TypeEvaluator接口,evaluate()方法。 这允许您使用的动画制作器在动画的当前点为动画属性返回适当的值。 该FloatEvaluator类演示如何做到这一点:

public class FloatEvaluator implements TypeEvaluator {

    public Object evaluate(float fraction, Object startValue, Object endValue) {
        float startFloat = ((Number) startValue).floatValue();
        return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
    }
}

注:当ValueAnimator(或ObjectAnimator)运行时,它计算动画的电流经过的分数(0之间的值,1),然后计算的内插版本,具体取决于您所使用的插补器。内插的分数是你的什么TypeEvaluator接收通过fraction参数,因此您不必计算动画值时,要考虑到插补器。

利用内插器


内插器定义动画中的具体值如何作为时间的函数计算。 例如,您可以指定动画在整个动画中线性发生,这意味着动画在整个时间内均匀移动,或者您可以指定动画以使用非线性时间,例如,使用在开始或结束时的加速或减速动画。

动画系统中的内插器接收来自动画制作者的分数,其代表动画的经过时间。 插值器修改这个分数以与它想要提供的动画的类型一致。 Android系统提供了一组在公共内插的android.view.animation package。 如果这些都不满足您的需求,您可以实现TimeInterpolator接口,并创建自己的。

作为一个例子,缺省内插器如何AccelerateDecelerateInterpolatorLinearInterpolator计算内插的分数比较如下。 在LinearInterpolator对过去部分没有影响。 该AccelerateDecelerateInterpolator加速进入动画和减速出来。 以下方法定义了这些内插器的逻辑:

** AccelerateDecelerateInterpolator **

public float getInterpolation(float input) {
    return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
}

** LinearInterpolator **

public float getInterpolation(float input) {
    return input;
}

下表表示由这些内插器针对持续1000ms的动画计算的近似值:

经过毫秒 经过分数/内插分数(线性) 内插分数(加速/减速)
0 0 0
200 .2 .1
400 .4 .345
600 .6 .8
800 .8 .9
1000 1 1

如表所示, LinearInterpolator改变以相同的速度,.2值每一个通过200毫秒。 该AccelerateDecelerateInterpolator的变化速度比的数值LinearInterpolator 600毫秒和1000毫秒之间的200毫秒和600毫秒和慢之间。

指定关键帧


一个Keyframe对象由一时间/值对,可以让你在动画的特定时间定义一个特定的状态。 每个关键帧也可以有自己的插值器,以控制动画在上一个关键帧的时间和该关键帧的时间之间的间隔中的行为。

实例化一个Keyframe对象,你必须使用的工厂方法之一ofInt()ofFloat()ofObject()获得相应的类型Keyframe。然后调用ofKeyframe()工厂方法来获取PropertyValuesHolder对象。一旦你的对象,你可以通过在获取动画PropertyValuesHolder对象,并以动画的对象。下面的代码片段演示了如何做到这一点:

Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation)
rotationAnim.setDuration(5000ms);

有关如何使用关键帧更完整的示例,请参阅 MultiPropertyAnimation在APIDemos样本。

动画视图


属性动画系统允许View对象的流线型动画,并且提供了超过视图动画系统的一些优点。 视图动画系统通过更改绘制对象的方式来转换视图对象。 这是在每个View的容器中处理的,因为View本身没有可操作的属性。 这导致View被动画化,但是View对象本身没有改变。 这导致诸如对象仍然存在于其原始位置的行为,即使它被绘制在屏幕上的不同位置。 在Android 3.0中,添加了新属性和相应的getter和setter方法以消除此缺点。

属性动画系统可以通过更改View对象中的实际属性来在屏幕上激活视图。 此外,视图还自动调用invalidate()方法来刷新,只要其属性被更改屏幕。 在新的属性View类,便于物业动画是:

  • translationXtranslationY:这些属性控制在何处查看位于作为从中由其布局容器设置其左边和顶部坐标的增量。* rotationrotationXrotationY:这些属性控制在2D(旋转rotation绕轴心点属性)和3D。
  • scaleXscaleY:这些属性控制绕其轴心点视图的2D缩放。
  • pivotXpivotY:这些属性控制枢轴点的位置,在其周围旋转和缩放变换发生。默认情况下,枢转点位于所述物体的中心。
  • xy:这些都是简单实用的属性来描述其容器查看的最后位置,左侧和顶部的价值观和translationX和translationY值的总和。
  • alpha:表示在视图的Alpha透明度。此值是1(不透明)默认情况下,以0代表完全透明值(不可见)。

要为View对象的属性(例如其颜色或旋转值)设置动画,您只需创建一个属性动画并指定要进行动画处理的View属性。 例如:

ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);

有关创建动画师的更多信息,请参阅与动画的部分 ValueAnimatorObjectAnimator

使用ViewPropertyAnimator进行动画处理

ViewPropertyAnimator提供了一个简单的方法来一个动画的几个属性View ,并行使用一个底层Animator对象。 它的行为很像ObjectAnimator ,因为它修改视图的财产的实际价值,但同时许多动画属性时更有效率。 此外,使用代码ViewPropertyAnimator更加简洁,更易于阅读。 下面的代码段示出了使用多个差异ObjectAnimator对象,一个单一的ObjectAnimatorViewPropertyAnimator时同时动画的x和y的图的属性。

** 多个ObjectAnimator对象 **

ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f);
ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(animX, animY);
animSetXY.start();

** 一个ObjectAnimator对象 **

PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();

** ViewPropertyAnimator **

myView.animate().x(50f).y(100f);

有关更多详细信息ViewPropertyAnimator,请参见相应的Android开发者 博客文章。

在XML声明动画


属性动画系统允许您使用XML声明属性动画,而不是以编程方式。 通过在XML中定义动画,您可以轻松地在多个活动中重复使用动画,并更轻松地编辑动画序列。

为了区分使用与那些使用旧的新的属性动画的API动画文件观看动画框架,开始与Android 3.1,你应该保存XML文件在属性动画res/animator/目录下。

以下属性动画类通过以下XML标记支持XML声明:

  • ValueAnimator -
  • ObjectAnimator -
  • AnimatorSet -
    下面的示例播放两套对象的动画顺序,第一组嵌套组一起编写两个对象的动画:

    
        
        
    
    

为了运行这个动画,必须在代码中的充气XML资源AnimatorSet对象,然后开始动画集之前为所有动画的目标对象。呼叫setTarget()设置的所有儿童的单一目标对象AnimatorSet的方便。下面的代码演示如何做到这一点:

AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,
    R.anim.property_animator);
set.setTarget(myObject);
set.start();

有关定义属性动画的XML语法信息,请参见动画资源。

你可能感兴趣的:(属性动画)