ValueAnimator
ObjectAnimator
TypeEvaluator
房地产动画系统是一个健壮的框架,它允许你动画几乎任何事情。您可以定义一个动画来改变任何对象属性随着时间的推移,不管是否吸引到屏幕上。属性动画改变属性的(对象)中一个字段值在一个指定的时间长度。动画,您指定您想要动画的对象属性,例如对象在屏幕上的位置,你想激活它多久,你想什么值之间的动画。
房地产动画系统允许您定义以下动画的特点:
首先,让我们复习一个动画如何与一个简单的例子。图1描述了一个假设的对象,是动画 x
属性,代表其水平位置在屏幕上。动画的持续时间设置为40 ms和旅行的距离是40像素。每10毫秒,这是默认的帧刷新率,物体水平10像素。在40 ms,动画停止,物体在水平位置40结束。这是动画与线性插值的一个例子,这意味着对象以一个恒定的速度移动。
您还可以指定动画非线性插值。图2演示了一个假想对象,加速的开头动画,动画的最后减慢。对象还是移动40像素在40 ms,但非线性。一开始,这个动画加速到一半然后从中点减慢,直到结束的动画。如图2所示,在开始和结束的距离的动画小于中间。
让我们来详细看看房地产动画系统的重要组件如何计算动画就像上面了。图3描述了主要的类是如何工作的。
的 ValueAnimator
对象跟踪你的动画的时机,如动画已经运行多长时间,和属性的当前值,它是动画。
的 ValueAnimator
封装了一个 TimeInterpolator
,它定义了动画插补和a TypeEvaluator
,它定义了如何计算属性值被动画。例如,在图2中, TimeInterpolator
将会使用 AccelerateDecelerateInterpolator
和 TypeEvaluator
将IntEvaluator
.
开始动画,创建一个 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 android.animation
。因为视图动画系统已经定义了许多插入器android.view.animation
,您可以使用这些房地产动画插入器系统。下面的表描述房地产动画系统的主要组件。
的 Animator
类提供了用于创建动画的基本结构。您通常不会直接使用这个类仅提供最小的功能,必须扩展完全支持动画值。以下子类扩展 Animator
:
类 | 描述 |
---|---|
ValueAnimator |
属性动画的主要时机引擎也计算动画的属性的值。动画的所有核心功能,计算值和包含的时间细节每个动画,动画是否重复信息,接收更新事件的侦听器,设置自定义类型评价的能力。有两块动画属性:计算动画值和设置这些值的对象和属性的动画。 ValueAnimator 不执行第二个,所以你必须倾听更新值计算的 ValueAnimator 和修改你想要动画的对象自己的逻辑。看到的部分动画与ValueAnimator为更多的信息。 |
ObjectAnimator |
的一个子类 ValueAnimator 允许你设定了一个目标对象和对象属性动画。这个类相应地更新属性计算新值时的动画。你想用 ObjectAnimator 大多数时候,因为它使动画值在目标对象的过程更加容易。然而,有时你想使用 ValueAnimator 直接原因 ObjectAnimator 有一些限制,比如要求特定的acessor方法出现在目标对象。 |
AnimatorSet |
提供一个机制来运行动画分组,这样他们的关系。你可以设置动画玩在一起,顺序,或在指定的延迟。看到的部分编排多个动画与动画集为更多的信息。 |
评价者告诉属性动画系统如何计算值对于一个给定的属性。他们把时机提供的数据 Animator
类,动画的起始和结束值,计算属性的动画值基于这些数据。房地产动画系统提供以下评估:
类/接口 | 描述 |
---|---|
IntEvaluator |
默认的评估者来计算值 int 属性。 |
FloatEvaluator |
默认的评估者来计算值 float 属性。 |
ArgbEvaluator |
默认颜色属性求值程序计算值表示为hexidecimal值。 |
TypeEvaluator |
一个接口,允许您创建自己的评估者。如果你不是一个动画对象属性 int , float ,或颜色,你必须实现 TypeEvaluator 接口来指定如何计算对象属性的动画值。你也可以指定一个自定义的 TypeEvaluator 为 int , float 和颜色值,如果你想处理这些类型不同于默认的行为。看到的部分使用TypeEvaluator为更多的信息关于如何编写一个定制的评估者。 |
一次在一个动画插入器定义了特定的值如何计算作为时间的函数。例如,您可以指定在整个动画动画发生线性,这意味着动画动作均匀,或您可以指定动画使用非线性时间,例如,开始加速和减速的动画。表3描述了包含在插入器android.view.animation
。如果没有一个插入器适合您的需要,提供实现 TimeInterpolator
界面和创建自己的。看到用插入器如何编写一个自定义插入器的更多信息。
类/接口 | 描述 |
---|---|
AccelerateDecelerateInterpolator |
插入器的变化速度缓慢开始和结束但加速通过中间。 |
AccelerateInterpolator |
插入器的变化速度开始缓慢,然后加速。 |
AnticipateInterpolator |
一个插入器的改变开始后退然后前进。 |
AnticipateOvershootInterpolator |
向前向后插入器的改变开始,将超过目标值,最后回到最后的价值。 |
BounceInterpolator |
最后的插入器改变反射。 |
CycleInterpolator |
指定数量的动画插入器的重复周期。 |
DecelerateInterpolator |
插入器的变化速度很快开始,然后减慢。 |
LinearInterpolator |
一个插入器的变化速度是恒定的。 |
OvershootInterpolator |
插入器的改变将向前和过激的最后一个值然后回来。 |
TimeInterpolator |
一个接口,允许您实现自己的插入器。 |
的 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
使用提供的逻辑 MyTypeEvaluator
1000毫秒的时间, start()
方法运行。
前面的代码片段,然而,对一个对象,没有实际效果,因为 ValueAnimator
并不直接作用于对象或属性。最可能的事,你要做的是修改你想要动画的对象,这些计算值。这可以通过定义的听众 ValueAnimator
妥善处理重要事件在动画的寿命,如帧更新。当实现侦听器,您可以获得特定框架的计算值刷新通过调用 getAnimatedValue()
。有关监听器的更多信息,请参阅部分动画的听众.
的 ObjectAnimator
的一个子类 ValueAnimator
(在前一节中讨论)和结合了计时引擎和价值计算 ValueAnimator
能够激活一个命名一个目标对象的属性。这使得动画任何对象容易得多,因为你不再需要实现ValueAnimator.AnimatorUpdateListener
,因为动画属性自动更新。
实例化一个 ObjectAnimator
类似于一个 ValueAnimator
,但你也指定对象和对象的属性的名称(作为字符串)的值之间的动画:
ObjectAnimator anim = ObjectAnimator.ofFloat(foo, "alpha", 0f, 1f); anim.setDuration(1000); anim.start();
有 ObjectAnimator
更新属性正确,你必须做到以下几点:
set()
。因为 ObjectAnimator
自动更新在动画属性,它必须能够访问属性setter方法。例如,如果属性名 foo
,你需要有一个 setFoo()
方法。如果这个setter方法不存在,你有三个选择:
ValueAnimator
代替。 values...
在其中的一个参数 ObjectAnimator
工厂方法,它被认为是结束动画的价值。因此,对象的动画属性必须有一个getter函数用于获取动画的起始值。getter函数必须的形式 get()
。例如,如果属性名 foo
,你需要有一个 getFoo()
方法。 ObjectAnimator
。例如,你必须有 targetObject.setPropName(float)
和 targetObject.getPropName(float)
如果你构建以下ObjectAnimator
: ObjectAnimator.ofFloat(targetObject, "propName", 1f)
invalidate()
方法在一个视图迫使屏幕重绘与更新的���画本身的值。你这样做的 onAnimationUpdate()
回调。例如,动画可移动对象的颜色属性只会更新屏幕重绘时,对象本身。等观点,所有的属性setter setAlpha()
和 setTranslationX()
无效的观点正确,所以你不需要使视图无效当调用这些方法与新值。有关监听器的更多信息,请参阅部分动画的听众.在很多情况下,你想玩一个动画这取决于当另一个动画开始或结束。Android系统让你动画捆绑为一个 AnimatorSet
,这样你就可以同时指定是否开始动画,顺序,或在指定的延迟。你也可以嵌套 AnimatorSet
对象在每个其他。
从下面的示例代码弹球(修改为简单起见)扮演以下示例 Animator
对象以下列方式:
bounceAnim
. squashAnim1
, squashAnim2
, stretchAnim1
, stretchAnim2
在同一时间。 bounceBackAnim
. 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()
在视图屏幕的力量区域重新划分与新动画本身的值。例如,动画可移动对象的颜色属性只会更新屏幕重绘时,对象本身。等观点,所有的属性setter setAlpha()
和 setTranslationX()
无效的观点正确,所以你不需要使视图无效当调用这些方法与新值。
您可以扩展 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和布局的变化 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
属性来 true
ViewGroup。例如:
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="@+id/verticalContainer"
android:animateLayoutChanges="true" />
自动将该属性设置为true的视图添加或删除从ViewGroup ViewGroup剩下的意见。
如果你想要动画的类型是未知的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
变化的速度比的值 LinearInterpolator
200毫秒到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);
有关创建动画师的更多信息,请参阅部分动画ValueAnimator和ObjectAnimator.
的 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中,可以很容易地重用你的动画更容易在多个活动和编辑动画序列。
区分动画文件使用新的房地产动画api从那些使用遗留视图动画框架,从Android 3.1开始,你应该保存属性动画的XML文件 res/animator/
目录(而不是 res/anim/
)。使用 animator
目录名称是可选的,但必要的如果你想要使用的布局编辑器工具在Eclipse ADT插件(ADT 11.0.0 +),因为ADT只搜索 res/animator/
目录属性动画资源。
以下属性动画类XML声明支持以下XML标记:
ValueAnimator
- - - - - -
ObjectAnimator
- - - - - -
AnimatorSet
- - - - - -
下面的例子中两组对象动画顺序,第一个嵌套组一起玩两个对象的动画:
android:ordering="sequentially"> android:propertyName="x" android:duration="500" android:valueTo="400" android:valueType="intType"/> android:propertyName="y" android:duration="500" android:valueTo="300" android:valueType="intType"/> android:propertyName="alpha" android:duration="500" android:valueTo="1f"/>
为了运行这个动画,必须抬高XML资源代码中的一个 AnimatorSet
对象,然后设置目标对象的所有动画在动画开始前集。 setTarget()
设置一个目标对象的所有儿童 AnimatorSet
作为一个方便。下面的代码显示了如何做到这一点:
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext, R.anim.property_animator); set.setTarget(myObject); set.start();
信息定义属性的XML语法动画,明白了动画资源.
ValueAnimator
ObjectAnimator
TypeEvaluator
房地产动画系统是一个健壮的框架,它允许你动画几乎任何事情。您可以定义一个动画来改变任何对象属性随着时间的推移,不管是否吸引到屏幕上。属性动画改变属性的(对象)中一个字段值在一个指定的时间长度。动画,您指定您想要动画的对象属性,例如对象在屏幕上的位置,你想激活它多久,你想什么值之间的动画。
房地产动画系统允许您定义以下动画的特点:
首先,让我们复习一个动画如何与一个简单的例子。图1描述了一个假设的对象,是动画 x
属性,代表其水平位置在屏幕上。动画的持续时间设置为40 ms和旅行的距离是40像素。每10毫秒,这是默认的帧刷新率,物体水平10像素。在40 ms,动画停止,物体在水平位置40结束。这是动画与线性插值的一个例子,这意味着对象以一个恒定的速度移动。
您还可以指定动画非线性插值。图2演示了一个假想对象,加速的开头动画,动画的最后减慢。对象还是移动40像素在40 ms,但非线性。一开始,这个动画加速到一半然后从中点减慢,直到结束的动画。如图2所示,在开始和结束的距离的动画小于中间。
让我们来详细看看房地产动画系统的重要组件如何计算动画就像上面了。图3描述了主要的类是如何工作的。
的 ValueAnimator
对象跟踪你的动画的时机,如动画已经运行多长时间,和属性的当前值,它是动画。
的 ValueAnimator
封装了一个 TimeInterpolator
,它定义了动画插补和a TypeEvaluator
,它定义了如何计算属性值被动画。例如,在图2中, TimeInterpolator
将会使用 AccelerateDecelerateInterpolator
和 TypeEvaluator
将IntEvaluator
.
开始动画,创建一个 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 android.animation
。因为视图动画系统已经定义了许多插入器android.view.animation
,您可以使用这些房地产动画插入器系统。下面的表描述房地产动画系统的主要组件。
的 Animator
类提供了用于创建动画的基本结构。您通常不会直接使用这个类仅提供最小的功能,必须扩展完全支持动画值。以下子类扩展 Animator
:
类 | 描述 |
---|---|
ValueAnimator |
属性动画的主要时机引擎也计算动画的属性的值。动画的所有核心功能,计算值和包含的时间细节每个动画,动画是否重复信息,接收更新事件的侦听器,设置自定义类型评价的能力。有两块动画属性:计算动画值和设置这些值的对象和属性的动画。 ValueAnimator 不执行第二个,所以你必须倾听更新值计算的 ValueAnimator 和修改你想要动画的对象自己的逻辑。看到的部分动画与ValueAnimator为更多的信息。 |
ObjectAnimator |
的一个子类 ValueAnimator 允许你设定了一个目标对象和对象属性动画。这个类相应地更新属性计算新值时的动画。你想用 ObjectAnimator 大多数时候,因为它使动画值在目标对象的过程更加容易。然而,有时你想使用 ValueAnimator 直接原因 ObjectAnimator 有一些限制,比如要求特定的acessor方法出现在目标对象。 |
AnimatorSet |
提供一个机制来运行动画分组,这样他们的关系。你可以设置动画玩在一起,顺序,或在指定的延迟。看到的部分编排多个动画与动画集为更多的信息。 |
评价者告诉属性动画系统如何计算值对于一个给定的属性。他们把时机提供的数据 Animator
类,动画的起始和结束值,计算属性的动画值基于这些数据。房地产动画系统提供以下评估:
类/接口 | 描述 |
---|---|
IntEvaluator |
默认的评估者来计算值 int 属性。 |
FloatEvaluator |
默认的评估者来计算值 float 属性。 |
ArgbEvaluator |
默认颜色属性求值程序计算值表示为hexidecimal值。 |
TypeEvaluator |
一个接口,允许您创建自己的评估者。如果你不是一个动画对象属性 int , float ,或颜色,你必须实现 TypeEvaluator 接口来指定如何计算对象属性的动画值。你也可以指定一个自定义的 TypeEvaluator 为 int , float 和颜色值,如果你想处理这些类型不同于默认的行为。看到的部分使用TypeEvaluator为更多的信息关于如何编写一个定制的评估者。 |
一次在一个动画插入器定义了特定的值如何计算作为时间的函数。例如,您可以指定在整个动画动画发生线性,这意味着动画动作均匀,或您可以指定动画使用非线性时间,例如,开始加速和减速的动画。表3描述了包含在插入器android.view.animation
。如果没有一个插入器适合您的需要,提供实现 TimeInterpolator
界面和创建自己的。看到用插入器如何编写一个自定义插入器的更多信息。
类/接口 | 描述 |
---|---|
AccelerateDecelerateInterpolator |
插入器的变化速度缓慢开始和结束但加速通过中间。 |
AccelerateInterpolator |
插入器的变化速度开始缓慢,然后加速。 |
AnticipateInterpolator |
一个插入器的改变开始后退然后前进。 |
AnticipateOvershootInterpolator |
向前向后插入器的改变开始,将超过目标值,最后回到最后的价值。 |
BounceInterpolator |
最后的插入器改变反射。 |
CycleInterpolator |
指定数量的动画插入器的重复周期。 |
DecelerateInterpolator |
插入器的变化速度很快开始,然后减慢。 |
LinearInterpolator |
一个插入器的变化速度是恒定的。 |
OvershootInterpolator |
插入器的改变将向前和过激的最后一个值然后回来。 |
TimeInterpolator |
一个接口,允许您实现自己的插入器。 |
的 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
使用提供的逻辑 MyTypeEvaluator
1000毫秒的时间, start()
方法运行。
前面的代码片段,然而,对一个对象,没有实际效果,因为 ValueAnimator
并不直接作用于对象或属性。最可能的事,你要做的是修改你想要动画的对象,这些计算值。这可以通过定义的听众 ValueAnimator
妥善处理重要事件在动画的寿命,如帧更新。当实现侦听器,您可以获得特定框架的计算值刷新通过调用 getAnimatedValue()
。有关监听器的更多信息,请参阅部分动画的听众.
的 ObjectAnimator
的一个子类 ValueAnimator
(在前一节中讨论)和结合了计时引擎和价值计算 ValueAnimator
能够激活一个命名一个目标对象的属性。这使得动画任何对象容易得多,因为你不再需要实现ValueAnimator.AnimatorUpdateListener
,因为动画属性自动更新。
实例化一个 ObjectAnimator
类似于一个 ValueAnimator
,但你也指定对象和对象的属性的名称(作为字符串)的值之间的动画:
ObjectAnimator anim = ObjectAnimator.ofFloat(foo, "alpha", 0f, 1f); anim.setDuration(1000); anim.start();
有 ObjectAnimator
更新属性正确,你必须做到以下几点:
set()
。因为 ObjectAnimator
自动更新在动画属性,它必须能够访问属性setter方法。例如,如果属性名 foo
,你需要有一个 setFoo()
方法。如果这个setter方法不存在,你有三个选择:
ValueAnimator
代替。 values...
在其中的一个参数 ObjectAnimator
工厂方法,它被认为是结束动画的价值。因此,对象的动画属性必须有一个getter函数用于获取动画的起始值。getter函数必须的形式 get()
。例如,如果属性名 foo
,你需要有一个 getFoo()
方法。 ObjectAnimator
。例如,你必须有 targetObject.setPropName(float)
和 targetObject.getPropName(float)
如果你构建以下ObjectAnimator
: ObjectAnimator.ofFloat(targetObject, "propName", 1f)
invalidate()
方法在一个视图迫使屏幕重绘与更新的���画本身的值。你这样做的 onAnimationUpdate()
回调。例如,动画可移动对象的颜色属性只会更新屏幕重绘时,对象本身。等观点,所有的属性setter setAlpha()
和 setTranslationX()
无效的观点正确,所以你不需要使视图无效当调用这些方法与新值。有关监听器的更多信息,请参阅部分动画的听众.在很多情况下,你想玩一个动画这取决于当另一个动画开始或结束。Android系统让你动画捆绑为一个 AnimatorSet
,这样你就可以同时指定是否开始动画,顺序,或在指定的延迟。你也可以嵌套 AnimatorSet
对象在每个其他。
从下面的示例代码弹球(修改为简单起见)扮演以下示例 Animator
对象以下列方式:
bounceAnim
. squashAnim1
, squashAnim2
, stretchAnim1
, stretchAnim2
在同一时间。 bounceBackAnim
. 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()
在视图屏幕的力量区域重新划分与新动画本身的值。例如,动画可移动对象的颜色属性只会更新屏幕重绘时,对象本身。等观点,所有的属性setter setAlpha()
和 setTranslationX()
无效的观点正确,所以你不需要使视图无效当调用这些方法与新值。
您可以扩展 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和布局的变化 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
属性来 true
ViewGroup。例如:
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="@+id/verticalContainer"
android:animateLayoutChanges="true" />
自动将该属性设置为true的视图添加或删除从ViewGroup ViewGroup剩下的意见。
如果你想要动画的类型是未知的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
变化的速度比的值 LinearInterpolator
200毫秒到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);
有关创建动画师的更多信息,请参阅部分动画ValueAnimator和ObjectAnimator.
的 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中,可以很容易地重用你的动画更容易在多个活动和编辑动画序列。
区分动画文件使用新的房地产动画api从那些使用遗留视图动画框架,从Android 3.1开始,你应该保存属性动画的XML文件 res/animator/
目录(而不是 res/anim/
)。使用 animator
目录名称是可选的,但必要的如果你想要使用的布局编辑器工具在Eclipse ADT插件(ADT 11.0.0 +),因为ADT只搜索 res/animator/
目录属性动画资源。
以下属性动画类XML声明支持以下XML标记:
ValueAnimator
- - - - - -
ObjectAnimator
- - - - - -
AnimatorSet
- - - - - -
下面的例子中两组对象动画顺序,第一个嵌套组一起玩两个对象的动画:
android:ordering="sequentially"> android:propertyName="x" android:duration="500" android:valueTo="400" android:valueType="intType"/> android:propertyName="y" android:duration="500" android:valueTo="300" android:valueType="intType"/> android:propertyName="alpha" android:duration="500" android:valueTo="1f"/>
为了运行这个动画,必须抬高XML资源代码中的一个 AnimatorSet
对象,然后设置目标对象的所有动画在动画开始前集。 setTarget()
设置一个目标对象的所有儿童 AnimatorSet
作为一个方便。下面的代码显示了如何做到这一点:
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext, R.anim.property_animator); set.setTarget(myObject); set.start();
信息定义属性的XML语法动画,明白了动画资源.