怎么定义块的属性何种属性可以用于控制动画开始和结束值?

属性动画系统是一个允許你对几乎任何事情进行的动画操作的健壮的框架你可以怎么定义块的属性一个属性动画来改变任何对象的某一属性,即使这个对象不能够在屏幕上显示一个属性动画在指定的时间内改变对象的一个属性值(成员变量),而你要做的是指定哪一个属性被“动画”例如對象在屏幕上的位置,动画持续多久以及在动画始末时刻的属性值。

  • 持续时间:属性动画默认的持续时间为300ms;
  • 时间插值器:指定在动画歭续时间内属性值以何种速率从起始值变化到默认值;
  • 重复次数和行为:指定单此动画执行完毕的时候是否继续正向重复执行,或者反姠执行以及动画重复的字数;
  • 动画集合:指定一个包含多个属性进行“动画”的动画组(Group);
  • 帧刷新时间:指定动画执行过程中,帧与幀之间的刷新时间默认值为10ms,但在真实应用程序中它取决于系统是否繁忙以及系统的处理速度。

视图动画叒称为补间动画(Tween)视图动画系统仅仅具备为视图(View)对象提供动画的能力,它对非视图对象(non-View objects)无能为力事实上,视图动画对于视圖对象而言也只在很少的方面起作用例如大小、旋转可行,但背景色就不起作用了

视图动画的另一个不足就是它改变的只是视图对象嘚“外表”,而非视图对象本身例如,通过视图动画让一个视图对象在屏幕上进行移动移动前位置为A,移动后位置为B即移动后与移動前“不在”同一个位置,但该视图对象的真实位置依然在AB位置的内容只是系统绘出(drawn)的“虚假”图形,如果要操作这个视图对象必须实现自己的操作逻辑。假如使用属性动画操作上述视图对象它的位置就是真实的发生了变化。

属性动画无论对视图对象还是非视图對象都其作用并且其作用范围涵盖颜色、位置、大小或者一切目标对象怎么定义块的属性的任何属性。

然而视图动画由于具备代码量哽少,耗时较短的特点当视图动画能够满足我们的需求的时候,不必使用属性动画在不同的情景下选择更高效的动画系统,彰显出了兩种动画系统(属性与视图)存在的意义

Animator:该类提供了创建属性动画的的基本结构,通常情况下不会直接使用该类因为它提供了佷少的方法来支持操作动画属性值。大部分情况下我们使用的是其子类

ValueAnimator:继承自Animator,它是主要的在动画过程中计算某一时刻属性值的计算引擎。它具备所有的核心功能方法包括每一个动画的时序细节,动画是否重复的信息***到的更新时间,以及设置自怎么定义块的屬性属性值类型计算器的能力

属性动画的实现主要包括两方便的内容:一方面是计算不同时刻的属性值,另一方面是将计算出来的属性徝赋值给目标对象然而ValueAnimator是不能够实现第二方面的,因此必须自己***属性值的更新并将其修改在目标对象上

ObjectAnimator:继承自ValueAnimator,它允许我们在指定对象属性的时候同时指定目标对象当计算出一个对应于某一时刻的新的属性值时,该类会自动更新目标对象的对应属性的属性值夶部分时间我们都在使用ObjectAnimator,因为它让新的属性值作用于目标对象的过程更为简单但是,我们有些时候不得不直接使用ValueAnimator因为ObjectAnimator有一些限制:例如要求目标对象必须具备一些特定的方法。

AnimatorSet:该类提供了多个属性动画“协调工作”的途径不同属性动画之间可以“同步执行”,亦可以“依次执行”或者“延时执行”。

TypeEvaluator:接口用于告诉系统将要改变的对象属性是什么类型的,以及如何计算要改变的属性该接ロ的实现类依靠Animator提供的时序数据和属性始末值,来计算动画过程中各个时刻的属性值系统主要提供了如下实现类。

IntEvaluator:是系统提供的默认嘚用于计算属性值为int类型的计算器

FloatEvaluator:是系统提供的默认的用于计算属性值为float类型的计算器。

ArgbEvaluator:系统提供的默认的用于计算属性值为十六進制的色值类型的计算器

当然,如果你要操作的目标对象的目标属性不在上述范围内你就需要(必须)实现TypeEvaluator接口来指定如何计算属性嘚动画值。除此之外你也可以通过自怎么定义块的属性实现TypeEvaluator接口,为intfloat,argb(color)类型的属性提供不同于系统默认的处理行为

TimeInterpolator:时间插值器(接口),用于指定在动画持续的过程中属性值在单位时间内步进的增量大小,也就是属性值变化的速率系统提供了如下实现类(鉯下列出的实现类只是常用的)。

LinearInterpolator:表明在动画持续过程中属性值的变化速率是恒定的。

AccelerateInterpolator:表明在动画持续过程中属性值的变化速率昰一直增大的。

DecelerateInterpolator:表明在动画持续过程中属性值的变化速率是一直减小的。

AccelerateDecelerateInterpolator:表明在动画持续过程中属性值的变化速率是前半段一直增大,后半段持续减小的

CycleInterpolator:为重复的属性动画指定了属性值的变化速率按照正弦曲线改变。

当然如果系统提供的时间插值器不能够满足我们的需求,我们可以实现TimeInterpolator接口来构造时间插值

当属性值类型非int,float的时候可以进行如下操作:

上述两段代码中,並不能真实的作用于任何一个对象因为ValueAnimator不能够直接操作对象或属性。想要解决这个问题我们可以在ValueAnimator怎么定义块的属性一个接口来适时哋处理诸如帧更新的时间,在实现这个接口的时候我们可以通过调用getAnimatedValue()方法来获得为每一帧计算出来的属性值。

ObjectAnimator整合了時序引擎和ValueAnimator的值计算能力因此它可以完成对目标对象的指定属性的“属性动画 ”的操作。为了让对任何对象都能够更简单的实现属性动畫我们不必再实现ValueAnimator.AnimatorUpdateListener接口,因为指定的属性会自动更新

初始化ObjectAnimator和ValueAnimator是相似的,不同的是初始化ObjectAnimator的时候要指定目标对象和该对象的属性名稱(String类型),以及动画始末该属性的属性值例如:

为了确保指定属性在动画持续的过程中能够自动更新,必须注意以下几点:

  1. 目标对象嘚目标属性必须具有setter方法如果该属性的setter方法不存在,可以:
    • 如果权限允许增加setter方法;
    • 如果权限允许,写一个包裹类(wrapper),该包裹类应具囿setter方法并指向原始目标对象的目标属性;
  2. 如果在对ObjectAnimator的工厂方法传实参的时候values…的实参只传了一个值,该值将是动画结束的属性值为了系统能够取到动画开始的属性值,目标对象的目标属性必须具备getter方法
  3. 在指定属性动画的始末属性值的时候,始末属性值的类型必须和getter方法(如果该方法是必需的)和setter方法中参数的类型相一致比如:targetObject.setPropName(float) and
  4. 当操作的对象是视图对象的“可见属性”(颜色,大小)时可能需要我們自己调用invalidate()强制使屏幕重绘对象本身。这步操作需要在onAnimationUpdate()回调方法中完成视图对象的所有setter方法,例如setAlpha()setTranslationX()都能够使视图对象实时的重绘因此这些属性在设置新值得时候不必考虑重绘的问题。

在许多时候一个动画的开始可能取决于另一个动画的开始或結束。Android系统允许使用AnimatorSet组织不同的属性动画以便我们可以指定不同动画间的播放形式是同步、异步或是延时。当然也可以将一个AnimatorSet对象嵌叺另一个AnimatorSet对象中。

我们可以在动画执行的过程中***重要的事件

为布局的改变添加属性动画

和能够为视图对潒提供简单的属性动画一样,属性动画系统也有能力为ViewGroup对象提供动画

可以自怎么定义块的属性我们自己的动画效果,方法如下:

实现该接口仅仅需要实现一个evaluate()方法该方法需要返回一个在动画过程中的某一时刻合适的目标属性值。例如FloatEvaluator的实现过程为:

注意:當ValueAnimator或ObjectAnimator运行的时候它计算从动画开始,到当前时刻已经过去的部分(介于0-1之间的数);然后计算我们使用(传入)的插值器版本。插值器部分的内容就是TypeEvaluator中接收到的fraction参数因此在计算目标属性某一个的属性值的时候不必再考虑插值器的影响。

一个插值器作为一個时间的函数怎么定义块的属性了如何影响动画过程中目标属性的属性值。例如可以指定动画线性的发生,意味着在整个时间内均匀嘚移动卡给你;当然也可以使用非线性时间比如开始加速,末尾减速

动画系统中的插值器接收一个来自Animators(代表动画已经过去的时间)嘚分数。插值器修改这个分数使结果一致于预期的目标。系统在android.view.animation包下提供了一系列公共的插值器如果这些都不适合我们,可以实现TimeInterpolator接ロ来创造属于自己的插值器

一个Keyframe对象包含一对“时间/值”对,这个“时间/值”对用于指定属性动画在特定时间的条件下的特定状态每一个Keyframe可以有属于它本身的插值器,用来控制动画从上一个Keyframe的时间值到这一个Keyframe对象的时间值之间的动画的行为

属性动画系统优化了一些针对目标对象是视图对象的方法。我们知道视图动画(补间动画)系统通过改变绘制视图方法的方法改造视图对潒,这在每一个视图对象所在的容器(container:ViewGroup)中被处理因为视图对象本身并没有属性可以被修改。结果是视图开始了动画但视图对象本身并没有发生变化(移动的是幻影,本身没有动)从Android 3.0开始,添加了新的属性和相应的setter、getter方法以避免上述漏洞

属性动画可以通过改变真實的属性值在屏幕上操作视图对象。除此之外视图对象党旗属性发生改变的时候可以自动调用invalidate()方法来刷新屏幕进行重绘。在View类中助于属性动画的新属性有:

  • pivotX和pivotY:参考位置围绕该点进行缩放或旋转。默认是对象的中心;
  • x和y:简单实用的用来描述在容器中的最终位置的属性;

ViewPropertyAnimator提供了一个简单的方法仅用一个Animator对象来并行处理View对象的少量的属性。它的作用很像ObjectAnimator因为它修改了视图对象的真实屬性值,且更加高效除此之外,使用ViewPropertyAnimator的代码更加简明易懂下面是不同方法的对比,效果是同时修改视图对象的x和y属性

在XML文件中声明属性动画

属性动画系统允许在xml文件中声明属性动画,在xml文件中怎么定义块的属性属性动画更以更加方便的在多个activityΦ复用,并可以更加简单的调整动画的顺序

属性动画的xml文件应保存在res/animator/文件夹下,下面是声明属性动画类的的标签:

为了使用这个属性动畫必须使用AnimatorSet对象来填充xml资源,然后设置目标对象实例代码如下:

参考资料

 

随机推荐