视图动画,只能设置插值器;但对于 Animator 而言,不仅可以设置插值器,还可以设置 Evaluator。
3.2.1 自定义插值器
插值器就是用来控制动画的区间值如何被计算出来的。
1、系统自带插值器
|
|
在 TimeInterpolator 的代码里,它只有一个函数 float getInterpolation(float input)。
- 参数 input:input 是 Float 类型的,它的取值范围是 0 ~ 1,表示当前动画的进度。取 0 时表示动画刚开始,取 1 时表示动画结束,取 0.5 时表示动画中间的位置,其他以此类推。它是时间概念。
- 返回值:表示当前实际想要显示的进度。取值可以超过 ,也可以小于 0。超过 1 表示已经超过目标值,小于 0 表示小于开始位置。
而 AccelerateDecelerateInterpolator 返回的显示进度值为:
input 是从 0 到 1,即cos(π) 到 cos(2π) 的结果值是从 -1 到 1。最终返回结果还是从 0 到 1,但是由于 Math.cos() 导致速率变化了,先加速后减速。
2、自定义插值器示例
想要先减速后加速的效果,可以重写 getInterpolation 方法。
由于 tan 函数曲线变化不明显,导致加速减速效果也不明显,趋向于匀速。
使用
3.2.2 Evaluator
1. 概述
上图所述的 4 个步骤的具体含义是:
1)ofInt(0,400):表示指定动画的数值区间,从 0 运动到 400。
2)插值器:在动画开始后通过插值器会返回当前动画进度所对应的数值进度,这个数值进度是以小数表示的,如 0.2。
3)Evaluator:我们通过监听器拿到的是当前动画所对应的具体数值,而不是用小数表示的数值。那么必须有一个地方会根据当前的数值进度将其转换为对应的数值,这个地方就是 Evaluator。Evaluator 用于将从插值器返回的数值进度(小数,0 - 1.0)转换成对应的数值。
4)监听器返回:在 AnimatorUpdateListener 监听器中使用 animation.getAnimatedValue() 函数拿到 Evaluator 中返回的数值。
2. 各种 Evaluator
插值器返回的小数值表示的是当前动画的数值进度,这对于无论是使用 ofFloat() 函数还是使用 ofInt() 函数定义的动画都是适用的。因为无论是什么动画,它的进度必然在 0~1 之间。0 表示还没开始,1 表示动画结束,这对于任何动画都是适用的。
而 Evaluator 则不一样,它把插值器返回的小数进度转换成当前数值进度所对应的值。如果使用 ofInt() 函数来定义动画,动画中的值应该都是 Integer 类型的,所对应的 Evaluator 在返回值时,必然返回 Integer 类型的值;如果使用 ofFloat() 函数来定义动画,动画中的值都是 Float 类型的,Evaluator 在返回值时,必然返回 Float 类型的值。
所以,每种定义方式所对应的 Evaluator 必然是它专用的。Evaluator 专用的原因在于动画数值类型不一样,在通过 Evaluator 返回时会报强转错误,所以只有在动画数值类型一样时,所对应的 Evaluator 才能通用。ofInt() 函数对应的 Evaluator 类名为 IntEvaluator,而 ofFloat() 函数对应的 Evaluator 类名为 FloatEvaluator。
通过 animator.setEvaluator() 函数来设置 Evaluator,比如:
ofInt() 函数的默认 Evaluator 是 IntEvaluator,而 ofFloat() 函数的默认 Evaluator 则是 FloatEvaluator。
可以继续看下 IntEvaluator 的源码:
在 IntEvaluator 中只有一个函数 evaluate(float fraction, Integer startValue, Integer endValue):
- fraction 参数就是插值器中的返回值,表示当前动画的数值进度,以百分制的小数表示。
- startValue 和 endValue 分别对应 ofInt(int start,int end) 函数中 start 和 end 的数值。假设当我们定义的动画 ofInt(100,400) 进行到数值进度 20% 的时候,那么此时在 evaluate() 函数中,fraction 的值就是 0.2,startValue 的值是 100,endValue 的值是 400。
- 返回值就是当前数值进度所对应的具体数值,这个数值就是我们在 AnimatorUpdateListener 监听器中通过 animation.getAnimatedValue() 函数得到的数值。
总之:既可以通过重写插值器改变数值进度来改变数值位置,也可以通过改变 Evaluator 中数值进度所对应的具体数值来改变数值位置。
3. 简单实现 Evaluator
自定义 MyEvaluator,并设定一个位移量。
使用:
4. 自定义 Evaluator 实现倒序输出
|
|
5. ArgbEvaluator
除 IntEvaluator 和 FloatEvaluator 外,在 android.animation 包下还有另一个 Evaluator,名为 ArgbEvaluator,它是用来实现颜色值过渡转换的。
示例:
实现原理: