属性动画(Property Animation)从android 3.0(Level 11)引入以来,备受开发者的青睐。相对于视图动画(View Animation),属性动画框架更加健壮,属性动画不仅可以操作视图对象(View Object)而且可以操作非视图对象(non-View Object),并且视图动画也不存在视图对象的种种限制(只针对视图对象特定属性Translation、Scale、Rotate、Alpha可操作,而且改变的只是视图的绘制位置,无法改变事件的响应位置等)。本文主要对属性动画在执行时的对象方法调用过程进行记录,帮助理解属性动画执行的原理。
一、属性动画属性默认值说明:
1、 Duration:动画执行总时间,默认值为300ms;
2、 动画刷新时间间隔(刷新帧率):默认值为10ms,默认情况下动画执行过程中视图刷新间隔为10ms,此参数虽然可设,但是依赖于设备性能;
3、TypeEvaluator:默认情况下属性动画提供了两种求值类型:IntEvaluator和FloatEvaluator,动画执行过程中会根据给定的属性初始和结束值的类型确定调用哪种求值类 型,如果属性值类型不是Int和Float类型的话,要显示设置求值类型。
二、执行过程解说:
Animator类是属性动画的抽象基类,定义了创建属性动画的基础结构,在实现属性动画时一般不会直接拿此类来扩展。ValueAnimator类直接继承于Animator类,实现了动画执行的核心功能。下面就拿该类解说属性动画的执行过程,假设duration=40 ms,刷新时间间隔10 ms为例。
1、 根据设定的动画总时长Duration以及刷新帧率计算刷新时间节点,根据假设,刷新时间点分别为:[0 ms, 10 ms, 20 ms, 30 ms,40 ms];
2、 ValueAnimator将刷新时间节点转化成0--1的浮点数,分别为:[0/40, 10/40, 20/40, 30/40, 40/40] = [0.0, 0.25, 0.5, 0.75, 1.0];
3、 ValueAnimator根据设定的时间插值器(TimeInterpolator),调用其方法 getInterpolation(float input) 将时间分值转化为插值分值:
①LinearInterpolator:其getInterpolation(float input) 方法的实现为:
public float getInterpolation(float input) {
return input;
}
则,对应的插值分值分别为:[0.0, 0.25, 0.5, 0.75, 1.0];
②AccelerateDecelerateInterpolator:其getInterpolation(float input) 实现为:
public float getInterpolation(float input) {
return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
}
则,其对应的插值分值分别为:[0.0, 0.15, 0.5, 0.85, 1.0];
4、ValueAnimator调用默认类型的TypeEvaluator,根据设定的属性的初始及结束值,计算出每个刷新节点上属性的值,假如动画操作的是对象的 横坐标 x 属性,且初始值为0 px,结束值为40 px ,则:
① LinearInterpolator 下对应的各个刷新时间点上的 x 属性值分别为(由于初始和结束值类型为int型,所以调用IntEvaluator):):
[((int)(0+0.0*(40-0)), ((int)(0+0.25*(40-0)), ((int)(0+0.5*(40-0)), ((int)(0+0.75*(40-0)), ((int)(0+1.0*(40-0))] = [0, 10, 20, 30, 40];
整个执行过程如图:
② AccelerateDecelerateInterpolator下对应的各个刷下时间点上的 x 属性值分别为(由于初始和结束值类型为int型,所以调用IntEvaluator):
[((int)(0+0.0*(40-0)),((int)( 0+0.15*(40-0)),((int)(0+ 0.5*(40-0)), ((int)(0+0.85*(40-0)), ((int)(0+1.0*(40-0))] = [0, 6, 20, 34, 40];
整个执行过程如图:
四、ValueAnimator类调用的图示:
ValueAnimator类的主要实现机制就是根据时序计算动画所操纵属性的当前值,它包含了动画执行过程中的属性计算值、时序细节、重复次数、更新事件监听回调以及设置自定义求值类型的能力等。属性动画的实现包含两部分内容:计算属性的动画值和将这些值设置到对象的该属性上。ValueAnimator类只实现了属性值的计算,但不负责将属性值设置到对象的相应属性上。所以,必须自己设置属性值改变的监听,然后根据自己想要实现的动画逻辑更新对象的相应属性。如下图:
五、简单示例:
ValueAnimator animation = ValueAnimator.ofFloat(0.0f, 1.0f);
animation.setDuration(1000);
animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float alpha = (float) animation.getAnimatedValue();
mAnimView.setAlpha(alpha);//mAnimView为待执行动画的View
}
});
animation.start();