属性动画



属性动画

房地产动画系统是一个健壮的框架,它允许你动画几乎任何事情。您可以定义一个动画来改变任何对象属性随着时间的推移,不管是否吸引到屏幕上。属性动画改变属性的(对象)中一个字段值在一个指定的时间长度。动画,您指定您想要动画的对象属性,例如对象在屏幕上的位置,你想激活它多久,你想什么值之间的动画。

房地产动画系统允许您定义以下动画的特点:

  • 持续时间:您可以指定一个动画的持续时间。默认的长度是300 ms。
  • 插值:您可以指定属性的值是如何计算作为动画的当前时间的函数。
  • 重复计数和行为:您可以指定是否要有一个动画重复当它到达的时间和多少次重复动画。您还可以指定你想要播放的动画。设置反向扮演动画反复向前然后向后,直到到达重复出现的次数。
  • 动画设置:您可以动画进行逻辑分组后一起玩或顺序或指定的延迟。
  • 帧刷新延迟:您可以指定多长时间刷新你的动画帧。默认设置为每10毫秒刷新,但您的应用程序可以更新帧的速度最终依赖于多忙系统整体和系统如何快速服务底层的计时器。

属性动画是如何工作的


首先,让我们复习一个动画如何与一个简单的例子。图1描述了一个假设的对象,是动画 x属性,代表其水平位置在屏幕上。动画的持续时间设置为40 ms和旅行的距离是40像素。每10毫秒,这是默认的帧刷新率,物体水平10像素。在40 ms,动画停止,物体在水平位置40结束。这是动画与线性插值的一个例子,这意味着对象以一个恒定的速度移动。

图1所示。一个线性动画的例子

您还可以指定动画非线性插值。图2演示了一个假想对象,加速的开头动画,动画的最后减慢。对象还是移动40像素在40 ms,但非线性。一开始,这个动画加速到一半然后从中点减慢,直到结束的动画。如图2所示,在开始和结束的距离的动画小于中间。

图2。一个非线性动画的例子

让我们来详细看看房地产动画系统的重要组件如何计算动画就像上面了。图3描述了主要的类是如何工作的。

图3。动画是如何计算

 ValueAnimator对象跟踪你的动画的时机,如动画已经运行多长时间,和属性的当前值,它是动画。

 ValueAnimator封装了一个 TimeInterpolator,它定义了动画插补和a TypeEvaluator,它定义了如何计算属性值被动画。例如,在图2中, TimeInterpolator将会使用 AccelerateDecelerateInterpolator TypeEvaluatorIntEvaluator.

开始动画,创建一个 ValueAnimator并赋予它的起始和结束值属性,你想动画,动画的持续时间。当你打电话 start()动画的开始。在整个动画 ValueAnimator计算一个经过分数在0和1之间,根据动画的持续时间和多长时间运行。经过分数代表的时间百分比动画已经完成,0意味着0%和1 100%的意义。例如,在图1中,经过分数在t = 10 ms。25因为总持续时间t = 40毫秒。

 ValueAnimator完成计算的分数间隔,它调用吗 TimeInterpolator目前,一个插值计算分数。一个插值部分花费的一部分映射到一个新的部分,考虑了时间插值设置。例如,在图2中,因为动画慢慢加速,插值分数,。15日,小于运行分数,。25日在t = 10女士在图1中,插值分数总是经过分数一样。

当插值计算分数, ValueAnimator调用适当的 TypeEvaluator计算属性的价值,你是动画,基于插值的分数,起始值和结束值的动画。例如,在图2中,插值分数。15日在t = 10毫秒,所以当时的属性的值。15 X(40 - 0),或6。

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

属性动画不同于视图动画如何


视图动画系统提供的功能只有动画 View对象,所以,如果你想非动画View对象,您必须执行自己的代码。视图动画系统也受到限制,只公开了几方面的 View对象动画,比如一个视图的缩放和旋转而不是背景颜色,例如。

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

随着房地产动画系统,这些约束是完全移除,你可以激活任何对象的任何属性(视图和non-Views)和对象本身实际上是修改。房地产动画系统也更健壮的方式进行动画。在高级别上,你指定动画师想要动画的属性,例如颜色、位置、大小和动画可以定义方面的插值和同步等多个动画师。

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

API概述


你可以找到大部分的房地产动画系统的api android.animation。因为视图动画系统已经定义了许多插入器android.view.animation,您可以使用这些房地产动画插入器系统。下面的表描述房地产动画系统的主要组件。

 Animator类提供了用于创建动画的基本结构。您通常不会直接使用这个类仅提供最小的功能,必须扩展完全支持动画值。以下子类扩展 Animator:

表1。动画师

描述
ValueAnimator 属性动画的主要时机引擎也计算动画的属性的值。动画的所有核心功能,计算值和包含的时间细节每个动画,动画是否重复信息,接收更新事件的侦听器,设置自定义类型评价的能力。有两块动画属性:计算动画值和设置这些值的对象和属性的动画。 ValueAnimator不执行第二个,所以你必须倾听更新值计算的 ValueAnimator和修改你想要动画的对象自己的逻辑。看到的部分动画与ValueAnimator为更多的信息。
ObjectAnimator 的一个子类 ValueAnimator允许你设定了一个目标对象和对象属性动画。这个类相应地更新属性计算新值时的动画。你想用 ObjectAnimator大多数时候,因为它使动画值在目标对象的过程更加容易。然而,有时你想使用 ValueAnimator直接原因 ObjectAnimator有一些限制,比如要求特定的acessor方法出现在目标对象。
AnimatorSet 提供一个机制来运行动画分组,这样他们的关系。你可以设置动画玩在一起,顺序,或在指定的延迟。看到的部分编排多个动画与动画集为更多的信息。

评价者告诉属性动画系统如何计算值对于一个给定的属性。他们把时机提供的数据 Animator类,动画的起始和结束值,计算属性的动画值基于这些数据。房地产动画系统提供以下评估:

表2。评价者

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

一次在一个动画插入器定义了特定的值如何计算作为时间的函数。例如,您可以指定在整个动画动画发生线性,这意味着动画动作均匀,或您可以指定动画使用非线性时间,例如,开始加速和减速的动画。表3描述了包含在插入器android.view.animation。如果没有一个插入器适合您的需要,提供实现 TimeInterpolator界面和创建自己的。看到用插入器如何编写一个自定义插入器的更多信息。

表3。插入器

类/接口 描述
AccelerateDecelerateInterpolator 插入器的变化速度缓慢开始和结束但加速通过中间。
AccelerateInterpolator 插入器的变化速度开始缓慢,然后加速。
AnticipateInterpolator 一个插入器的改变开始后退然后前进。
AnticipateOvershootInterpolator 向前向后插入器的改变开始,将超过目标值,最后回到最后的价值。
BounceInterpolator 最后的插入器改变反射。
CycleInterpolator 指定数量的动画插入器的重复周期。
DecelerateInterpolator 插入器的变化速度很快开始,然后减慢。
LinearInterpolator 一个插入器的变化速度是恒定的。
OvershootInterpolator 插入器的改变将向前和过激的最后一个值然后回来。
TimeInterpolator 一个接口,允许您实现自己的插入器。

动画与ValueAnimator


 ValueAnimator某种类型的类允许您动画值期间通过指定一组动画 int, float通过动画、颜色值。你获得一个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之间的动画,开始计算的值 startPropertyValue endPropertyValue使用提供的逻辑 MyTypeEvaluator1000毫秒的时间, start()方法运行。

前面的代码片段,然而,对一个对象,没有实际效果,因为 ValueAnimator并不直接作用于对象或属性。最可能的事,你要做的是修改你想要动画的对象,这些计算值。这可以通过定义的听众 ValueAnimator妥善处理重要事件在动画的寿命,如帧更新。当实现侦听器,您可以获得特定框架的计算值刷新通过调用 getAnimatedValue()。有关监听器的更多信息,请参阅部分动画的听众.

动画与ObjectAnimator


 ObjectAnimator的一个子类 ValueAnimator(在前一节中讨论)和结合了计时引擎和价值计算 ValueAnimator能够激活一个命名一个目标对象的属性。这使得动画任何对象容易得多,因为你不再需要实现ValueAnimator.AnimatorUpdateListener,因为动画属性自动更新。

实例化一个 ObjectAnimator类似于一个 ValueAnimator,但你也指定对象和对象的属性的名称(作为字符串)的值之间的动画:

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

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

  • 的动画对象属性必须有一个setter函数(在驼峰式大小写)的形式 set<propertyName>()。因为 ObjectAnimator自动更新在动画属性,它必须能够访问属性setter方法。例如,如果属性名 foo,你需要有一个 setFoo()方法。如果这个setter方法不存在,你有三个选择:
    • setter方法添加到类如果你有权利这样做。
    • 使用一个包装器类,你有权利改变包装器接收的值与一个有效的setter方法和转发原始对象。
    • 使用 ValueAnimator代替。
  • 如果您指定只有一个值 values...在其中的一个参数 ObjectAnimator工厂方法,它被认为是结束动画的价值。因此,对象的动画属性必须有一个getter函数用于获取动画的起始值。getter函数必须的形式 get<propertyName>()。例如,如果属性名 foo,你需要有一个 getFoo()方法。
  • getter(如果需要)和setter方法的动画的属性必须使用相同类型的开始和结束值指定 ObjectAnimator。例如,你必须有 targetObject.setPropName(float) targetObject.getPropName(float)如果你构建以下ObjectAnimator:
     
    ObjectAnimator.ofFloat(targetObject, "propName", 1f)
  • 根据你属性或对象的动画,您可能需要调用 invalidate()方法在一个视图迫使屏幕重绘与更新的���画本身的值。你这样做的 onAnimationUpdate()回调。例如,动画可移动对象的颜色属性只会更新屏幕重绘时,对象本身。等观点,所有的属性setter setAlpha() setTranslationX()无效的观点正确,所以你不需要使视图无效当调用这些方法与新值。有关监听器的更多信息,请参阅部分动画的听众.

与AnimatorSet编排多个动画


在很多情况下,你想玩一个动画这取决于当另一个动画开始或结束。Android系统让你动画捆绑为一个 AnimatorSet,这样你就可以同时指定是否开始动画,顺序,或在指定的延迟。你也可以嵌套 AnimatorSet对象在每个其他。

从下面的示例代码弹球(修改为简单起见)扮演以下示例 Animator对象以下列方式:

  1. 戏剧 bounceAnim.
  2. 戏剧 squashAnim1, squashAnim2, stretchAnim1, 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样本。

动画的听众


你可以收听重要事件在一个动画的持续时间与下面描述的听众。

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

例如,弹球示例API演示创建一个 AnimatorListenerAdapter仅仅为 onAnimationEnd()回调函数:

ValueAnimatorAnimator 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对象变化的能力以及提供了一个简单的方法来动画视图对象本身。

你可以用动画在ViewGroup和布局的变化 LayoutTransition类。视图内ViewGroup可以通过动画出现和消失,当你将它们添加或删除它们从ViewGroup或当你调用一个视图 setVisibility()方法 VISIBLE,android.view。视图#隐形},或 GONE。ViewGroup剩下的意见也可以动画到新的位置当你添加或删除视图。你可以定义以下动画LayoutTransition对象通过调用 setAnimator()和传递 Animator对象与下列之一 LayoutTransition常量:

  • APPEARING——一个标志指示的动画项目出现在容器上运行。
  • CHANGE_APPEARING——一个标志显示动画运行在项改变由于容器中出现的一个新项。
  • DISAPPEARING——一个标志显示动画,运行在容器的东西正在消失。
  • CHANGE_DISAPPEARING——一个标志显示动画运行在项改变由于一个项目从容器中消失。

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

LayoutAnimations示例API演示显示了如何定义动画布局过渡,然后设置动画想要动画的视图对象。

LayoutAnimationsByDefault与其相应的layout_animations_by_default.xml布局资源文件说明如何启用默认布局viewgroup转换的XML。你唯一需要做的就是设置 android:animateLayoutchanges属性来 trueViewGroup。例如:

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

自动将该属性设置为true的视图添加或删除从ViewGroup ViewGroup剩下的意见。

使用TypeEvaluator


如果你想要动画的类型是未知的Android系统,您可以创建自己的评估者通过实现 TypeEvaluator接口。已知类型的Android系统 int, float或一个颜色,是支持的 IntEvaluator, FloatEvaluator, ArgbEvaluator评估类型。

只有一个方法来实现的 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界面和创建自己的。

作为一个例子,如何默认插入器 AccelerateDecelerateInterpolator LinearInterpolator下面的计算插值分数进行比较。的 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;
}

下表代表了这些近似计算值为一个持续1000毫秒的动画插入器:

经过女士 经过分数/插值分数(线性) 插值分数(加速/减速)
0 0 0
200年 2 1。
400年 。4 .345
600年 6 。8
800年 。8 。9
1000年 1 1

如表所示, LinearInterpolator在相同的速度,改变了值。2每200毫秒。的 AccelerateDecelerateInterpolator变化的速度比的值 LinearInterpolator200毫秒到600毫秒和慢600毫秒到1000毫秒之间。

指定关键帧


一个 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样本。

动画视图


房地产动画系统允许简化动画视图对象和offerse几个优势视图动画系统。视图动画系统转换视图对象通过改变他们的方式。这是每个视图容器的处理,因为视图本身没有属性操作。这导致视图动画,但没有造成改变视图对象本身。这导致行为如一个对象仍然存在于其原始位置,即使是在屏幕上画在不同的位置。在Android 3.0,新添加了属性和相应的getter和setter方法来消除这个缺点。

房地产动画系统可以动画视图在屏幕上通过改变实际的属性视图中的对象。此外,意见还自动调用 invalidate()方法以其属性被更改时刷新屏幕。的新属性 View类,促进房地产动画:

  • translationX translationY:这些属性控制视图的位置作为一个三角洲从其左和顶部坐标设置布局容器。
  • rotation, rotationX, rotationY在2 d:这些属性控制旋转(rotation在轴心点属性)和3 d。
  • scaleX scaleY:这些属性控制的2 d缩放视图围绕其轴心点。
  • pivotX pivotY:这些属性控制枢轴点的位置,旋转和缩放变换发生。默认情况下,枢轴点位于中心的对象。
  • x y:这些都是简单的工具属性来描述视图的最终位置的容器,左侧和顶部的总和值和translationX translationY值。
  • alpha:代表视图上的alpha透明度。这个值是1(不透明的)默认情况下,用一个值0表示完全透明(不可见)。

动画视图对象的属性,如颜色或旋转值,所有您需要做的是创建一个属性动画师和指定你想要的视图属性动画。例如:

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

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

动画与ViewPropertyAnimator

 ViewPropertyAnimator提供了一个简单的动画几个属性的方法 View同时,使用单一的基础 Animator对象。它的行为��像一个 ObjectAnimator,因为它修改视图的属性的实际值,但动画时更有效率的许多属性。此外,使用的代码 ViewPropertyAnimator更简洁,更容易阅读。下面的代码片段显示了使用多个的差异 ObjectAnimator对象,一个ObjectAnimator, ViewPropertyAnimator当同时动画 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/目录(而不是 res/anim/)。使用 animator目录名称是可选的,但必要的如果你想要使用的布局编辑器工具在Eclipse ADT插件(ADT 11.0.0 +),因为ADT只搜索 res/animator/目录属性动画资源。

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

下面的例子中两组对象动画顺序,第一个嵌套组一起玩两个对象的动画:

<set android: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>

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

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

信息定义属性的XML语法动画,明白了动画资源.

属性动画

房地产动画系统是一个健壮的框架,它允许你动画几乎任何事情。您可以定义一个动画来改变任何对象属性随着时间的推移,不管是否吸引到屏幕上。属性动画改变属性的(对象)中一个字段值在一个指定的时间长度。动画,您指定您想要动画的对象属性,例如对象在屏幕上的位置,你想激活它多久,你想什么值之间的动画。

房地产动画系统允许您定义以下动画的特点:

  • 持续时间:您可以指定一个动画的持续时间。默认的长度是300 ms。
  • 插值:您可以指定属性的值是如何计算作为动画的当前时间的函数。
  • 重复计数和行为:您可以指定是否要有一个动画重复当它到达的时间和多少次重复动画。您还可以指定你想要播放的动画。设置反向扮演动画反复向前然后向后,直到到达重复出现的次数。
  • 动画设置:您可以动画进行逻辑分组后一起玩或顺序或指定的延迟。
  • 帧刷新延迟:您可以指定多长时间刷新你的动画帧。默认设置为每10毫秒刷新,但您的应用程序可以更新帧的速度最终依赖于多忙系统整体和系统如何快速服务底层的计时器。

属性动画是如何工作的


首先,让我们复习一个动画如何与一个简单的例子。图1描述了一个假设的对象,是动画 x属性,代表其水平位置在屏幕上。动画的持续时间设置为40 ms和旅行的距离是40像素。每10毫秒,这是默认的帧刷新率,物体水平10像素。在40 ms,动画停止,物体在水平位置40结束。这是动画与线性插值的一个例子,这意味着对象以一个恒定的速度移动。

图1所示。一个线性动画的例子

您还可以指定动画非线性插值。图2演示了一个假想对象,加速的开头动画,动画的最后减慢。对象还是移动40像素在40 ms,但非线性。一开始,这个动画加速到一半然后从中点减慢,直到结束的动画。如图2所示,在开始和结束的距离的动画小于中间。

图2。一个非线性动画的例子

让我们来详细看看房地产动画系统的重要组件如何计算动画就像上面了。图3描述了主要的类是如何工作的。

图3。动画是如何计算

 ValueAnimator对象跟踪你的动画的时机,如动画已经运行多长时间,和属性的当前值,它是动画。

 ValueAnimator封装了一个 TimeInterpolator,它定义了动画插补和a TypeEvaluator,它定义了如何计算属性值被动画。例如,在图2中, TimeInterpolator将会使用 AccelerateDecelerateInterpolator TypeEvaluatorIntEvaluator.

开始动画,创建一个 ValueAnimator并赋予它的起始和结束值属性,你想动画,动画的持续时间。当你打电话 start()动画的开始。在整个动画 ValueAnimator计算一个经过分数在0和1之间,根据动画的持续时间和多长时间运行。经过分数代表的时间百分比动画已经完成,0意味着0%和1 100%的意义。例如,在图1中,经过分数在t = 10 ms。25因为总持续时间t = 40毫秒。

 ValueAnimator完成计算的分数间隔,它调用吗 TimeInterpolator目前,一个插值计算分数。一个插值部分花费的一部分映射到一个新的部分,考虑了时间插值设置。例如,在图2中,因为动画慢慢加速,插值分数,。15日,小于运行分数,。25日在t = 10女士在图1中,插值分数总是经过分数一样。

当插值计算分数, ValueAnimator调用适当的 TypeEvaluator计算属性的价值,你是动画,基于插值的分数,起始值和结束值的动画。例如,在图2中,插值分数。15日在t = 10毫秒,所以当时的属性的值。15 X(40 - 0),或6。

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

属性动画不同于视图动画如何


视图动画系统提供的功能只有动画 View对象,所以,如果你想非动画View对象,您必须执行自己的代码。视图动画系统也受到限制,只公开了几方面的 View对象动画,比如一个视图的缩放和旋转而不是背景颜色,例如。

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

随着房地产动画系统,这些约束是完全移除,你可以激活任何对象的任何属性(视图和non-Views)和对象本身实际上是修改。房地产动画系统也更健壮的方式进行动画。在高级别上,你指定动画师想要动画的属性,例如颜色、位置、大小和动画可以定义方面的插值和同步等多个动画师。

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

API概述


你可以找到大部分的房地产动画系统的api android.animation。因为视图动画系统已经定义了许多插入器android.view.animation,您可以使用这些房地产动画插入器系统。下面的表描述房地产动画系统的主要组件。

 Animator类提供了用于创建动画的基本结构。您通常不会直接使用这个类仅提供最小的功能,必须扩展完全支持动画值。以下子类扩展 Animator:

表1。动画师

描述
ValueAnimator 属性动画的主要时机引擎也计算动画的属性的值。动画的所有核心功能,计算值和包含的时间细节每个动画,动画是否重复信息,接收更新事件的侦听器,设置自定义类型评价的能力。有两块动画属性:计算动画值和设置这些值的对象和属性的动画。 ValueAnimator不执行第二个,所以你必须倾听更新值计算的 ValueAnimator和修改你想要动画的对象自己的逻辑。看到的部分动画与ValueAnimator为更多的信息。
ObjectAnimator 的一个子类 ValueAnimator允许你设定了一个目标对象和对象属性动画。这个类相应地更新属性计算新值时的动画。你想用 ObjectAnimator大多数时候,因为它使动画值在目标对象的过程更加容易。然而,有时你想使用 ValueAnimator直接原因 ObjectAnimator有一些限制,比如要求特定的acessor方法出现在目标对象。
AnimatorSet 提供一个机制来运行动画分组,这样他们的关系。你可以设置动画玩在一起,顺序,或在指定的延迟。看到的部分编排多个动画与动画集为更多的信息。

评价者告诉属性动画系统如何计算值对于一个给定的属性。他们把时机提供的数据 Animator类,动画的起始和结束值,计算属性的动画值基于这些数据。房地产动画系统提供以下评估:

表2。评价者

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

一次在一个动画插入器定义了特定的值如何计算作为时间的函数。例如,您可以指定在整个动画动画发生线性,这意味着动画动作均匀,或您可以指定动画使用非线性时间,例如,开始加速和减速的动画。表3描述了包含在插入器android.view.animation。如果没有一个插入器适合您的需要,提供实现 TimeInterpolator界面和创建自己的。看到用插入器如何编写一个自定义插入器的更多信息。

表3。插入器

类/接口 描述
AccelerateDecelerateInterpolator 插入器的变化速度缓慢开始和结束但加速通过中间。
AccelerateInterpolator 插入器的变化速度开始缓慢,然后加速。
AnticipateInterpolator 一个插入器的改变开始后退然后前进。
AnticipateOvershootInterpolator 向前向后插入器的改变开始,将超过目标值,最后回到最后的价值。
BounceInterpolator 最后的插入器改变反射。
CycleInterpolator 指定数量的动画插入器的重复周期。
DecelerateInterpolator 插入器的变化速度很快开始,然后减慢。
LinearInterpolator 一个插入器的变化速度是恒定的。
OvershootInterpolator 插入器的改变将向前和过激的最后一个值然后回来。
TimeInterpolator 一个接口,允许您实现自己的插入器。

动画与ValueAnimator


 ValueAnimator某种类型的类允许您动画值期间通过指定一组动画 int, float通过动画、颜色值。你获得一个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之间的动画,开始计算的值 startPropertyValue endPropertyValue使用提供的逻辑 MyTypeEvaluator1000毫秒的时间, start()方法运行。

前面的代码片段,然而,对一个对象,没有实际效果,因为 ValueAnimator并不直接作用于对象或属性。最可能的事,你要做的是修改你想要动画的对象,这些计算值。这可以通过定义的听众 ValueAnimator妥善处理重要事件在动画的寿命,如帧更新。当实现侦听器,您可以获得特定框架的计算值刷新通过调用 getAnimatedValue()。有关监听器的更多信息,请参阅部分动画的听众.

动画与ObjectAnimator


 ObjectAnimator的一个子类 ValueAnimator(在前一节中讨论)和结合了计时引擎和价值计算 ValueAnimator能够激活一个命名一个目标对象的属性。这使得动画任何对象容易得多,因为你不再需要实现ValueAnimator.AnimatorUpdateListener,因为动画属性自动更新。

实例化一个 ObjectAnimator类似于一个 ValueAnimator,但你也指定对象和对象的属性的名称(作为字符串)的值之间的动画:

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

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

  • 的动画对象属性必须有一个setter函数(在驼峰式大小写)的形式 set<propertyName>()。因为 ObjectAnimator自动更新在动画属性,它必须能够访问属性setter方法。例如,如果属性名 foo,你需要有一个 setFoo()方法。如果这个setter方法不存在,你有三个选择:
    • setter方法添加到类如果你有权利这样做。
    • 使用一个包装器类,你有权利改变包装器接收的值与一个有效的setter方法和转发原始对象。
    • 使用 ValueAnimator代替。
  • 如果您指定只有一个值 values...在其中的一个参数 ObjectAnimator工厂方法,它被认为是结束动画的价值。因此,对象的动画属性必须有一个getter函数用于获取动画的起始值。getter函数必须的形式 get<propertyName>()。例如,如果属性名 foo,你需要有一个 getFoo()方法。
  • getter(如果需要)和setter方法的动画的属性必须使用相同类型的开始和结束值指定 ObjectAnimator。例如,你必须有 targetObject.setPropName(float) targetObject.getPropName(float)如果你构建以下ObjectAnimator:
     
    ObjectAnimator.ofFloat(targetObject, "propName", 1f)
  • 根据你属性或对象的动画,您可能需要调用 invalidate()方法在一个视图迫使屏幕重绘与更新的���画本身的值。你这样做的 onAnimationUpdate()回调。例如,动画可移动对象的颜色属性只会更新屏幕重绘时,对象本身。等观点,所有的属性setter setAlpha() setTranslationX()无效的观点正确,所以你不需要使视图无效当调用这些方法与新值。有关监听器的更多信息,请参阅部分动画的听众.

与AnimatorSet编排多个动画


在很多情况下,你想玩一个动画这取决于当另一个动画开始或结束。Android系统让你动画捆绑为一个 AnimatorSet,这样你就可以同时指定是否开始动画,顺序,或在指定的延迟。你也可以嵌套 AnimatorSet对象在每个其他。

从下面的示例代码弹球(修改为简单起见)扮演以下示例 Animator对象以下列方式:

  1. 戏剧 bounceAnim.
  2. 戏剧 squashAnim1, squashAnim2, stretchAnim1, 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样本。

动画的听众


你可以收听重要事件在一个动画的持续时间与下面描述的听众。

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

例如,弹球示例API演示创建一个 AnimatorListenerAdapter仅仅为 onAnimationEnd()回调函数:

ValueAnimatorAnimator 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对象变化的能力以及提供了一个简单的方法来动画视图对象本身。

你可以用动画在ViewGroup和布局的变化 LayoutTransition类。视图内ViewGroup可以通过动画出现和消失,当你将它们添加或删除它们从ViewGroup或当你调用一个视图 setVisibility()方法 VISIBLE,android.view。视图#隐形},或 GONE。ViewGroup剩下的意见也可以动画到新的位置当你添加或删除视图。你可以定义以下动画LayoutTransition对象通过调用 setAnimator()和传递 Animator对象与下列之一 LayoutTransition常量:

  • APPEARING——一个标志指示的动画项目出现在容器上运行。
  • CHANGE_APPEARING——一个标志显示动画运行在项改变由于容器中出现的一个新项。
  • DISAPPEARING——一个标志显示动画,运行在容器的东西正在消失。
  • CHANGE_DISAPPEARING——一个标志显示动画运行在项改变由于一个项目从容器中消失。

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

LayoutAnimations示例API演示显示了如何定义动画布局过渡,然后设置动画想要动画的视图对象。

LayoutAnimationsByDefault与其相应的layout_animations_by_default.xml布局资源文件说明如何启用默认布局viewgroup转换的XML。你唯一需要做的就是设置 android:animateLayoutchanges属性来 trueViewGroup。例如:

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

自动将该属性设置为true的视图添加或删除从ViewGroup ViewGroup剩下的意见。

使用TypeEvaluator


如果你想要动画的类型是未知的Android系统,您可以创建自己的评估者通过实现 TypeEvaluator接口。已知类型的Android系统 int, float或一个颜色,是支持的 IntEvaluator, FloatEvaluator, ArgbEvaluator评估类型。

只有一个方法来实现的 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界面和创建自己的。

作为一个例子,如何默认插入器 AccelerateDecelerateInterpolator LinearInterpolator下面的计算插值分数进行比较。的 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;
}

下表代表了这些近似计算值为一个持续1000毫秒的动画插入器:

经过女士 经过分数/插值分数(线性) 插值分数(加速/减速)
0 0 0
200年 2 1。
400年 。4 .345
600年 6 。8
800年 。8 。9
1000年 1 1

如表所示, LinearInterpolator在相同的速度,改变了值。2每200毫秒。的 AccelerateDecelerateInterpolator变化的速度比的值 LinearInterpolator200毫秒到600毫秒和慢600毫秒到1000毫秒之间。

指定关键帧


一个 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样本。

动画视图


房地产动画系统允许简化动画视图对象和offerse几个优势视图动画系统。视图动画系统转换视图对象通过改变他们的方式。这是每个视图容器的处理,因为视图本身没有属性操作。这导致视图动画,但没有造成改变视图对象本身。这导致行为如一个对象仍然存在于其原始位置,即使是在屏幕上画在不同的位置。在Android 3.0,新添加了属性和相应的getter和setter方法来消除这个缺点。

房地产动画系统可以动画视图在屏幕上通过改变实际的属性视图中的对象。此外,意见还自动调用 invalidate()方法以其属性被更改时刷新屏幕。的新属性 View类,促进房地产动画:

  • translationX translationY:这些属性控制视图的位置作为一个三角洲从其左和顶部坐标设置布局容器。
  • rotation, rotationX, rotationY在2 d:这些属性控制旋转(rotation在轴心点属性)和3 d。
  • scaleX scaleY:这些属性控制的2 d缩放视图围绕其轴心点。
  • pivotX pivotY:这些属性控制枢轴点的位置,旋转和缩放变换发生。默认情况下,枢轴点位于中心的对象。
  • x y:这些都是简单的工具属性来描述视图的最终位置的容器,左侧和顶部的总和值和translationX translationY值。
  • alpha:代表视图上的alpha透明度。这个值是1(不透明的)默认情况下,用一个值0表示完全透明(不可见)。

动画视图对象的属性,如颜色或旋转值,所有您需要做的是创建一个属性动画师和指定你想要的视图属性动画。例如:

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

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

动画与ViewPropertyAnimator

 ViewPropertyAnimator提供了一个简单的动画几个属性的方法 View同时,使用单一的基础 Animator对象。它的行为��像一个 ObjectAnimator,因为它修改视图的属性的实际值,但动画时更有效率的许多属性。此外,使用的代码 ViewPropertyAnimator更简洁,更容易阅读。下面的代码片段显示了使用多个的差异 ObjectAnimator对象,一个ObjectAnimator, ViewPropertyAnimator当同时动画 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/目录(而不是 res/anim/)。使用 animator目录名称是可选的,但必要的如果你想要使用的布局编辑器工具在Eclipse ADT插件(ADT 11.0.0 +),因为ADT只搜索 res/animator/目录属性动画资源。

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

下面的例子中两组对象动画顺序,第一个嵌套组一起玩两个对象的动画:

<set android: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>

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

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

信息定义属性的XML语法动画,明白了动画资源.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值