Property Animation
该属性动画系统是一个强大的框架,可以让您动画几乎任何事情。可以定义动画随时间而改变任何对象属性,无论它绘制到屏幕或没有。的属性动画改变属性的(一个字段中的对象),在指定的时间长度值。要动态的东西,你指定要进行动画处理,例如对象在屏幕上的位置,你要多久才能动画它,你想之间设置动画什么值的对象属性。
该物业动画系统允许您定义动画的以下特点:
持续时间:您可以指定动画的持续时间。默认长度为300毫秒。
时间插补:您可以指定该属性的值如何作为动画的当前运行时间的函数来计算。
重复计数和行为:您可以指定是否要当它到达的持续时间到底多少次重复的动画有一个动画重演。您也可以指定是否希望动画反向播放。将它设置为反向播放动画,然后向前向后反反复复,直到达到重复的次数。
动画集:您可以将动画成一起玩或顺序逻辑设置或指定的延迟之后。
帧刷新延迟:您可以指定多久刷新动画的帧。默认设置刷新每10毫秒,但速度在您的应用程序可以刷新帧最终取决于系统整体多么繁忙,系统如何能够快速的服务底层计时器。
如何物业动漫作品
首先,让我们对动画如何用一个简单的例子工程。图1描绘了动画与其x属性,它表示在屏幕上的其水平位置的假想对象。动画的持续时间设置为40毫秒,并以行进的距离是40个像素。每10毫秒,这是默认的帧刷新速率,目的是通过10个像素水平移动。在40毫秒结束时,动画停止,并且对象结束于水平位置40这是用线性内插的动画的例子,这意味着在一个恒定速度的物体移动。
图1.一个线性动画实施例
还可以指定动画具有非线性内插。图2示出了加速在动画的开始的假想对象,并在动画结束减速。对象仍移动40个像素在40毫秒的,但非直线。在开始的时候,这个动画加速到中间点不是从中间点,直到动画结束减速。如图2所示,行进的距离在开始和动画的端小于在中间。
图2的非线性动画实施例
让我们来看看如何属性动画系统的重要组成部分会计算像上面显示的那些动画的详细研究。图3描述了主类如何相互合作。
图3.动画如何计算
该ValueAnimator对象跟踪动画的时机,如多久动画已经运行,而且它是动画的属性的当前值。
所述ValueAnimator封装TimeInterpolator,它定义动画插值,和一个TypeEvaluator,它定义了如何计算属性值被动画。例如,在图2中,所使用的TimeInterpolator将AccelerateDecelerateInterpolator和TypeEvaluator将IntEvaluator。
要启动动画,营造ValueAnimator,并给它一个你想要的动画,用动画的持续时间沿线物业的开始和结束的值。当你调用的start()的动画开始。在整个动画时,ValueAnimator计算0和1之间经过的级分,基于该动画的持续时间和多少时间已过。所经过的分数表示在完成动画的时间百分比,0表示0%和1的含义100%。例如,在图1中,在t的经过分率= 10毫秒将是0.25,因为总的持续时间为t = 40毫秒。
当ValueAnimator完成计算经过的分数时,它调用当前设置TimeInterpolator,以计算内插级分。内插部分映射的经过馏分到一个新的分数,考虑到所设置的时间内插。例如,在图2中,因为动画缓慢加速时,内插的分数,约0.15,小于过去部分,.25,在t = 10毫秒。在图1中,内插的分数是总是相同的经过部分。
当计算内插级分,ValueAnimator调用相应TypeEvaluator,来计算要基于内插级分,起始值和动画的结束值动画,该属性的值。例如,在图2中,内插的分数为0.15在t = 10毫秒,所以当时该属性的值将是0.15×(40 - 1),或6。
该com.example.android.apis.animation包中的API演示示例项目提供了有关如何使用属性动画系统的例子很多。
如何物业动画从观看动画的区别
视图动画系统提供了唯一的动画视图对象的能力,所以如果你想制作动画的非视图对象,你必须实现自己的代码来做到这一点。视图动画系统也是制约的事实,它仅仅公开了一个查看对象的几个方面进行动画,诸如视图的缩放和旋转,但不是背景颜色,例如。
视图动画系统的另一个缺点是,它只是修改其视图被吸引,而不是实际的观本身。例如,如果你设置动画的按钮在屏幕上移动,按钮绘制正确的,但实际的位置,您可以点击按钮不会改变,所以你要实现你自己的逻辑来处理这个问题。
随着房地产动画系统,这些限制都完全去除,并且可以设置动画的任何对象(视图和非查看)任何财产和对象本身实际上被修改。该物业动画系统也是它执行动画的方式更加健壮。在一个较高的水平,分配动画师要进行动画处理的属性,如颜色,位置和大小,并可以定义,如插补和多个动画师的同步动画的各个方面。
该视图的动画系统,但是,花费较少的时间设置和需要更少的代码编写。如果观看动画完成,你需要做的一切,如果你现有的代码已经运作的,你想要的方式,就没有必要使用属性动画系统。它也可能是有意义如果利用情况,即同时使用动画系统针对不同的情况。
API概述
你可以发现,大部分的属性动画系统API的android.animation。因为视图动画系统已经在android.view.animation定义了许多插值,可以在属性动画系统使用的插值为好。下表描述了属性动画系统的主要组成部分。
Animator类提供用于创建动画的基本结构。你通常不直接使用这个类,因为它只是提供了最小的功能,必须扩展到完全支持动画值。下面的子类扩展动画:
表1.动画师
类说明
ValueAnimator的属性动画的主要定时引擎也计算值的属性进行动画处理。它具有所有这一切计算动画值,并包含每个动画的时序信息,相关信息的核心功能无论是动画重复,接收更新事件监听器,并设置自定义类型,评估的能力。有两片动画的属性:计算所述动画值和正在动画对象和属性上设置这些值。 ValueAnimator不进行第二块,所以你一定要听的更新由ValueAnimator计算值和修改要与自己的逻辑进行动画处理的对象。看到有ValueAnimator动画的更多信息一节。
ObjectAnimator ValueAnimator的子类,允许您设置一个目标对象和对象属性的动画。这个类相应地更新属性时,它计算用于动画的新值。你想用ObjectAnimator大部分时间,因为它使目标动画值的过程对象容易得多。但是,有时候想直接使用ValueAnimator因为ObjectAnimator有几个限制,比如需要特定acessor方法出现在目标对象上。
AnimatorSet使得它们相对于运行彼此提供一个机制,以组的动画一起。您可以设置动画一起玩,顺序,或在指定的延迟之后。请参阅有关创编与动画设置多个动画的更多信息一节。
评估人员告诉属性动画系统如何计算给定属性值。他们采取的是由动画类提供的定时数据,动画开始和结束值,并计算基于此数据属性的动画值。该属性动画系统提供以下评估:
表2.评价者
IntEvaluato在计算器的默认评估计算INT属性的值。
FloatEvaluator默认的评估来计算浮法属性的值。
ArgbEvaluator默认的评估来计算被表示为十六进制值的颜色属性的值。
TypeEvaluator的接口,使您可以创建自己的评估。如果您设置动画的对象属性不是一个int,float或颜色,你必须实现TypeEvaluator界面指定如何计算对象属性的动画值。您也可以指定整数,浮点,色值自定义TypeEvaluator还有,如果你想以不同的方式处理这些类型比默认的行为。请参阅有关使用TypeEvaluator有关如何编写自定义的评估更多信息一节。
一时间内插器限定在动画中的特定值的方式作为时间的函数来计算。例如,您可以指定动画在整个动画线性发生的,均匀的意思动画动作的整个时间,也可以指定动画使用非线性时间,例如,在开始加速,并在底了减速动画。表3描述了包含在android.view.animation插补器。如果没有提供插值适合您的需求,实现了TimeInterpolator接口,并创建自己的。请参阅使用插值有关如何编写自定义的内插的更多信息。
表3.内插器
类/接口描述
AccelerateDecelerateInterpolator其变动开工率,结束慢,但通过中间加速内插器。
AccelerateInterpolator内插器的变化,其速度开始慢慢出来,然后加速。
AnticipateInterpolator内插器,其开始变化,然后向后甩向前发展。
AnticipateOvershootInterpolator内插器,其变化落后开始,甩向前和过冲的目标值,然后最终返回到最终值。
BounceInterpolator内插器,其变化在反弹结束。
CycleInterpolator其动画周期的指定数目的重复内插器。
DecelerateInterpolator其变化率开始迅速出来,然后减速的插补器。
LinearInterpolator内插器的变化,其速度是恒定的。
OvershootInterpolator其变动甩向前冲过最后一个值然后回来内插器。
TimeInterpolator,可以让你实现自己的内插器的接口。
与ValueAnimator动画
该ValueAnimator类,可以通过指定一组整数,浮点或颜色值的动画动画通过某种类型的动画的持续时间值。您可以通过调用其工厂方法获得ValueAnimator:IofInt()
, ofFloat()
, or 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开始利用我的TypeEvaluator为1000毫秒的持续时间提供的逻辑计算动画startPropertyValue和结束属性值之间的值,在start()方法运行时。
ObjectAnimator anim = ObjectAnimator.ofFloat(foo, "alpha", 0f, 1f); anim.setDuration(1000); anim.start();要正确有ObjectAnimator更新属性,必须做到以下几点:
ObjectAnimator.ofFloat(targetObject, "propName", 1f)根据什么属性或对象的动画,你可能需要调用一个查看无效()方法强制屏幕更新的动画值重绘自身。您可以在onAnimationUpdate()回调做到这一点。例如,动画效果可绘制对象的颜色属性只造成对屏幕的更新时,该对象重绘自己。所有在查看属性制定者,如setAlpha()和setTranslationX的()正确无效视图,所以你不需要调用这些方法与新的值时无效视图。有关监听器的详细信息,请参阅动画听众部分。
bounceAnim
.squashAnim1
, squashAnim2
, stretchAnim1
, and stretchAnim2
at the same time.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的弹跳球样本。
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()); }动画布局更改ViewGroups
<LinearLayout android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="match_parent" android:id="@+id/verticalContainer" android:animateLayoutChanges="true" />
将此属性设置为true动画自动被添加或从的ViewGroup以及在的ViewGroup剩余的视图中删除视图。
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接收通过部分参数什么,所以你不必计算动画值时,要考虑到插补器。
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毫秒的动画计算的近似值:
ms elapsed | Elapsed fraction/Interpolated fraction (Linear) | Interpolated fraction (Accelerate/Decelerate) |
---|---|---|
0 | 0 | 0 |
200 | .2 | .1 |
400 | .4 | .345 |
600 | .6 | .8 |
800 | .8 | .9 |
1000 | 1 | 1 |
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);有关如何使用关键帧更完整的示例,请参阅APIDemos多属性动画样本。
ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);有关创建动画师的更多信息,请参阅与ValueAnimator和ObjectAnimator动画节。
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f); PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f); ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();or的差异,并且当同时动画的图的x和y属性的ViewPropertyAnimator。
ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f); ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f); AnimatorSet animSetXY = new AnimatorSet(); animSetXY.playTogether(animX, animY); animSetXY.start();One 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开发者博客文章。
<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>为了运行这个动画,必须在代码中的AnimatorSet对象充气XML资源,然后开始动画集之前为所有动画的目标对象。调用设定目标()设置为AnimatorSet的所有子作为一种方便的单一目标对象。下面的代码演示如何做到这一点:
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext, R.anim.property_animator); set.setTarget(myObject); set.start();有关定义属性动画XML语法的信息,请参阅参考资料动画。