通俗详解 Android 动画插值器与估值器

151 阅读3分钟

1. 动画的基本原理

动画的本质是​​属性随时间变化​​的过程。例如,一个按钮从位置 A 移动到位置 B,需要不断计算每一帧的位置。Android 动画系统通过两个核心组件实现这一过程:

  • ​插值器(Interpolator)​​:控制动画的“节奏”(如匀速、加速、弹跳)。
  • ​估值器(Evaluator)​​:根据节奏计算“具体属性值”(如坐标、颜色)。

2. 插值器(Interpolator):时间的魔法师

想象插值器是一个“时间变速器”,它决定了动画在不同时间点的进度比例(比如前慢后快)。它的核心是​​数学函数​​,输入是时间进度(0~1),输出是“调整后的进度”(可能小于0或大于1)。

2.1 源码结构

所有插值器继承自 BaseInterpolator,核心方法是 getInterpolation(float input)

  • ​参数 input​:动画已进行的时间比例(0 表示开始,1 表示结束)。
  • ​返回值​​:调整后的进度(例如输入 0.5,返回 0.25 表示此时进度只有 25%)。
2.2 常见插值器详解
  1. ​Linear(线性)​

    • ​效果​​:匀速动画。
    • ​公式​​:y = t
    • ​源码​​:直接返回输入值 input
  2. ​Accelerate(加速)​

    • ​效果​​:速度越来越快。
    • ​公式​​:y = t^(2×factor)(默认 factor=1,即 )。
    • ​示例​​:factor=2 时,动画会更快达到高速。
  3. ​Decelerate(减速)​

    • ​效果​​:速度越来越慢。
    • ​公式​​:y = 1 - (1 - t)^(2×factor)(默认 1 - (1 - t)²)。
  4. ​Bounce(弹跳)​

    • ​效果​​:像球落地后弹跳几次。

    • ​实现​​:通过分段二次函数模拟弹跳轨迹,例如:

      java
      Copy
      if (t < 0.3535) return 8*(1.1226t)^2;
      else if (t < 0.7408) return 8*(1.1226t - 0.54719)^2 + 0.7;
      ...
      
  5. ​Anticipate(回拉)​

    • ​效果​​:先向反方向移动一小段,再正向加速。
    • ​公式​​:y = t² × ((tension+1)t - tension)(默认 tension=2)。

3. 估值器(Evaluator):数值的计算器

插值器决定了“进度比例”,估值器则根据这个比例​​计算具体的属性值​​。例如,从位置 0 移动到 100,进度 50% 时,估值器会计算出 50。

3.1 源码结构

所有估值器实现 TypeEvaluator<T> 接口,核心方法是:

java
Copy
T evaluate(float fraction, T startValue, T endValue);
  • ​参数 fraction​:插值器调整后的进度(可能超出 0~1)。
  • ​参数 startValueendValue​:属性起始值和结束值。
  • ​返回值​​:当前属性值。
3.2 常见估值器
  1. ​IntEvaluator(整数计算)​

    • ​公式​​:result = start + (end - start) * fraction
    • ​示例​​:从 0 到 100,进度 0.5 时值为 50。
  2. ​ArgbEvaluator(颜色渐变)​

    • ​实现​​:将颜色拆分为 ARGB 四个通道,分别计算:

      java
      Copy
      int red = startRed + (int)(fraction * (endRed - startRed));
      // 同理计算 alpha、green、blue,再合并为最终颜色。
      

4. 协同工作流程

  1. ​时间流逝​​:系统计算已进行的时间比例 t(如 0.5)。
  2. ​插值器转换​​:通过 getInterpolation(t) 得到新的进度 fraction(可能被加速/减速)。
  3. ​估值器计算​​:根据 fraction 计算当前属性值(如位置、颜色)。

​示例​​:一个按钮在 2 秒内从 (0,0) 移动到 (200,0),使用 BounceInterpolator

  • 时间过半(t=1秒),插值器可能返回 fraction=0.7(进度更快)。
  • 估值器计算 X 坐标:0 + 0.7 * (200-0) = 140,此时按钮已超过中点。

5. 设计思考

  • ​插值器的数学本质​​:通过函数曲线控制动画节奏,例如平方函数()让初始速度更慢。
  • ​为什么需要估值器​​?属性类型多样(位置、颜色、旋转角度),需要专用计算逻辑。
  • ​ArgbEvaluator 的单例问题​​:虽然源码用单例,但构造方法未私有化,可能是框架内部优化,开发者无需关心。

6. 总结

  • ​插值器​​:决定动画“如何变化”(快慢、弹跳)。
  • ​估值器​​:决定动画“变化成什么值”(位置、颜色)。
  • ​组合使用​​:通过不同的插值器和估值器,可以实现丰富的动画效果,例如颜色渐变的加速效果,或旋转时的回弹。