Android 属性动画:插值器和估值器(上)

261 阅读4分钟

我们都知道,属性动画可以对某个属性做动画,而 插值器(TimeInterpolator) 和 估值器(TypeEvaluator) 在其中扮演了重要角色,下面先了解下 TimeInterpolator 和 TypeEvaluator 的基本概念和作用。

TimeInterpolator(时间插值器):

作用: 根据时间流逝的百分比计算出当前属性值改变的百分比。

系统已有的插值器: 

  • LinearInterpolator(线性插值器): 匀速动画。 

  • AccelerateDecelerateInterpolator(加速减速插值器): 动画两头慢,中间快。 

  • DecelerateInterpolator(减速插值器): 动画越来越慢。

TypeEvaluator(类型估值算法,即估值器):

作用: 根据当前属性改变的百分比来计算改变后的属性值。

系统已有的估值器: 

  • IntEvaluator: 针对整型属性 

  • FloatEvaluator: 针对浮点型属性 

  • ArgbEvaluator: 针对Color属性

那么 TimeInterpolator和 TypeEvaluator 是怎么协同工作的呢?

属性动画是对属性做动画,属性要实现动画,首先由 TimeInterpolator (插值器) 根据时间流逝的百分比计算出当前属性值改变的百分比,并且 插值器 将这个百分比返回,这个时候 插值器 的工作就完成了。

比如 插值器 返回的值是0.5,很显然我们要的不是0.5,而是当前属性的值,即当前属性变成了什么值,这就需要 估值器 根据当前属性改变的百分比来计算改变后的属性值,根据这个属性值,我们就可以设置当前属性的值了。

源码分析

上面的理论知识可能比较抽象,下面根据一个实例结合系统源码来分析一下:

下图表示一个匀速动画,采用了线性插值器和整型估值算法,在40ms内,View的x属性实现从0到40的变换。

图片

假如动画的默认刷新率为10ms/帧(各手机的刷新率不一样),该动画将分为5帧进行。

当动画进行到第三帧的时候,(x=20,t=20ms)当时间 t=20ms 的时候,时间流逝的百分比是 0.5(20/40=0.5) ,即时间过了一半。这个百分比不是我们最终想要的,我们关心的是x的变化,那么x应该变化多少呢?插值器和估值算法就起作用了。拿 线性插值器 来说,线性插值器 是实现 匀速动画 的,先看一下线性插值器 的源码:

图片

很显然,线性插值器 的返回值和输入值一样(看getInterpolation方法),因此 t=20ms 时 插值器 返回的值是 0.5(属性值改变的百分比),这意味着 x属性的改变是0.5。这个时候 插值器 的工作已经完成了,插值器 的工作就是根据时间流逝的百分比计算出当前属性值改变的百分比。

我们得到了当前属性改变的百分比是0.5,即50%。下一步就是要算出x具体变为了什么值,这个时候 估值算法 就起作用了,它的作用就是根据当前属性改变的百分比来计算改变后的属性值。我们先看看系统提供的 整型估值算法 的源码:

图片

上述代码中的 evaluate 方法 的三个参数分别表示 估值小数(fraction)这个fraction就是前面插值器计算出来的 属性值改变的百分比) ,开始值(startValue)和 结束值(endValue) 。对于我们的这个例子就是 0.5,0和40。我们将这三个值代入求值,即:0+0.5(40 - 0)=20。没错,这就是当 t=20ms 时 x=20 的由来。

其实对于 插值器和估值器 来说,除了系统提供的外,我们还可以自定义。实现方式也很简单,因为插值器和估值器都是一个接口,且内部都只有一个方法,我们只要实现接口就可以了,就可以做出很多绚丽的动画了。其中,自定义插值器 需要实现 Interpolator或者TimeInterpolator自定义估值器 需要实现TypeEvaluator

但是一般来说,插值器 使用系统的就足够了,估值器 自定义的可能会多一些,另外就是如果要对其他类型(非Int、float、color)做动画,必须自定义类型估值算法。

比如,我们想对一个非view对象进行动画操作,该如何实现呢? 下期我将用代码案例分享自定义插值器的使用。

(原文参考:blog.csdn.net/qq_24530405…