安卓动画系统主要由三个核心类构成,它们一起协作来创建各种动画效果。

ValueAnimator (数值生成器)

在安卓动画系统中,ValueAnimator 是一个核心概念,你可以把它理解为整个动画系统的“引擎”或者“数值生成器”。它本身并不会直接作用于任何视图或对象,它的唯一职责就是在一段时间内计算并生成一系列平滑变化的数值

ValueAnimator 的核心职责

  1. 定义数值范围: 你需要告诉 ValueAnimator 你的数值要从哪一个点开始,到哪一个点结束。例如,你可以让一个数值从 0 变化到 100,或者从 1.0f 变化到 0.5f。
  2. 定义时长: 你需要设定动画完成的总时长,单位是毫秒。
  3. 生成数值: 在动画运行时,ValueAnimator 会根据你设定的时长和数值范围,不断地计算出当前的中间值。

它为什么如此重要?

虽然 ValueAnimator 不直接改变视图,但它的灵活性和底层能力让它变得非常强大。它主要用于以下场景:

  • 驱动非视图属性的动画: 当你想为一个自定义 View 的绘制属性(比如半径、角度)或者一个非 View 对象(比如一个颜色值)做动画时,ObjectAnimator 无法直接工作,这时你就需要 ValueAnimator 来生成数值,然后手动将这些数值应用到你的属性上。
  • 复杂的动画逻辑: 如果你的动画需要同时驱动多个属性,或者需要根据动画进度来执行复杂的计算和逻辑,使用一个 ValueAnimator 来统一控制进度是最好的方法。
  • 为自定义 View 绘制动画: 在自定义 View 的 onDraw() 方法中,你经常需要根据动画的当前值来重新计算绘制内容,ValueAnimator 提供了最底层的数值支持。

ValueAnimator 的工作流程

你可以把它的工作流程想象成一个流水线:

  1. 启动: 你调用start()方法来启动动画。计算时间分数: 在动画运行的每一帧,ValueAnimator 都会计算一个从 0 到 1 的“时间分数”,表示动画已经进行的百分比。
  2. 计算动画分数: 它将这个“时间分数”传递给 Interpolator(插值器),Interpolator 根据其规则(比如加速或减速)返回一个“动画分数”。
  3. 生成动画值: ValueAnimator 使用这个“动画分数”来计算出当前的动画值。计算公式通常是:当前值 = 起始值 + (结束值 - 起始值) * 动画分数
  4. 触发监听器: 每当生成新的动画值,ValueAnimator 都会调用你设置的addUpdateListener 监听器,并把当前值传递给你。

使用示例

下面是一个简单的例子,演示如何使用 ValueAnimator 来改变一个 TextView 的字体大小。

// 1. 创建 ValueAnimator,设置数值范围
ValueAnimator animator = ValueAnimator.ofFloat(16f, 24f);
 
// 2. 设置动画时长
animator.setDuration(500); // 500毫秒
 
// 3. 添加监听器,手动应用数值
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        // 获取当前计算出的值
        float fontSize = (float) animation.getAnimatedValue();
 
        // 将这个值应用到 TextView 的字体大小上
        textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSize);
    }
});
 
// 4. 启动动画
animator.start();

通过这个例子你可以清楚地看到,ValueAnimator 只负责生成数值,而你需要通过 onAnimationUpdate 方法来获取这些值,并手动更新视图。

ObjectAnimator (属性动画师)

ObjectAnimator 是安卓动画系统中一个非常常用的类,它继承自 ValueAnimator,但比它的父类更强大、更方便。

如果说 ValueAnimator 是一个“数值生成器”,那么 ObjectAnimator 就是一个“属性动画师”,它能直接对对象的某个属性进行动画,省去了你手动更新属性的麻烦。

ObjectAnimator 的核心功能

它的核心功能是:在指定时间内,自动改变目标对象上某个命名属性的值

相比于 ValueAnimator 需要你手动在addUpdateListener中获取值并应用,ObjectAnimator 能够自动完成这一步。

你只需要告诉它:

  1. 要对哪个对象做动画(比如一个Button)。
  2. 要改变对象的哪个属性(比如alphatranslationXrotation)。
  3. 动画的数值范围(比如alpha从 1.0f 变到 0.0f)。
  4. 动画的时长

ObjectAnimator 的工作原理

ObjectAnimator 继承了 ValueAnimator 的所有功能,包括计算数值、使用插值器等。它在这些功能之上,又添加了自动查找和调用 setter 方法的能力。

当你创建ObjectAnimator时,它会做以下事情:

  1. 根据你指定的属性名(例如translationX),它会查找目标对象(例如你的Button)中对应的 setter 方法,也就是setTranslationX()
  2. 在动画运行时,ObjectAnimator 会像 ValueAnimator 一样计算出当前的动画值。
  3. 每计算出一个新值,它都会自动调用目标对象的setTranslationX()方法,并把这个新值作为参数传递进去。
    这样,视图的属性就自动被更新了,你不需要编写任何监听器来手动更新。

使用示例

我们用 ObjectAnimator 来实现一个让按钮渐渐消失的动画。

// 假设你有一个按钮
Button myButton = findViewById(R.id.my_button);
 
// 1. 创建 ObjectAnimator
// 第一个参数: 目标对象 myButton
// 第二个参数: 要改变的属性名 "alpha" (透明度)
// 第三个参数: 动画数值范围,从完全不透明(1.0f)到完全透明(0.0f)
ObjectAnimator animator = ObjectAnimator.ofFloat(myButton, "alpha", 1.0f, 0.0f);
 
// 2. 设置动画时长
animator.setDuration(1000); // 1秒
 
// 3. 启动动画
animator.start();

ValueAnimator 和 ObjectAnimator 的对比

特性ValueAnimatorObjectAnimator
功能纯粹的数值计算器,不直接作用于任何对象。继承自 ValueAnimator,并能自动改变对象的属性。
使用必须通过addUpdateListener监听器手动获取数值并更新属性。自动处理属性的更新,使用更简单方便。
应用场景适用于非视图属性动画、自定义 View 动画和复杂的逻辑控制。适用于视图的常见属性(如alpha, translationX, scaleY)动画。

总结: 在你能使用ObjectAnimator的情况下,优先使用它。它能让你的代码更简洁。只有当ObjectAnimator无法满足需求(比如要对没有 setter 方法的属性做动画,或者需要自定义动画逻辑)时,才使用 ValueAnimator

Interpolator (插值器)

Interpolator 在安卓动画中是一个非常重要的概念,它决定了动画的变化速率。你可以把 Interpolator 看作是动画的“速度控制器”或“缓动函数”。它不会改变动画的起点和终点,也不会改变动画的时长,但它会改变动画从起点到终点的过程

如果没有 Interpolator,动画默认是匀速的,也就是LinearInterpolator。但现实世界中的物体运动很少是匀速的,它们会有加速、减速,甚至弹跳的效果。

Interpolator 的作用就是模拟这些自然界中的运动规律,让你的动画看起来更生动、更自然。

Interpolator 的工作原理

Interpolator 本质上是一个数学函数,它接收一个 0 到 1 的“时间分数”,然后返回一个 0 到 1 的“动画分数”。

  • 时间分数 (Input):表示当前动画已经进行了多久,是一个均匀增长的值。例如,一个 1000 毫秒的动画,在 500 毫秒时,时间分数就是 0.5。
  • 动画分数 (Output):表示动画值应该变化到什么程度。这个值是非均匀的,由 Interpolator 根据时间分数计算得出。

ValueAnimator 就是使用这个动画分数来计算出当前动画值的。

当前值 = 起始值 + (结束值 - 起始值) * 动画分数

常用 Interpolator 类型

安卓系统内置了许多常用的 Interpolator,你可以直接拿来使用:

Interpolator 类型描述效果比喻
LinearInterpolator匀速变化,动画开始到结束速度不变。匀速直线运动的汽车。
AccelerateInterpolator先慢后快,动画在开始时速度慢,然后加速。刚启动的汽车,逐渐加速。
DecelerateInterpolator先快后慢,动画开始时速度快,然后减速。汽车准备停车,逐渐减速。
AccelerateDecelerateInterpolator开始和结束时慢,中间快。汽车启动后加速到一定速度,然后为停车减速。效果最自然。
BounceInterpolator像一个皮球落地后弹跳几次,最后静止。弹力球落地效果。
OvershootInterpolator动画值超过最终值,然后回弹到最终值。像一个物体用力过度,然后回退

如何使用 Interpolator

ObjectAnimatorValueAnimator 中,你可以通过 setInterpolator() 方法来设置它。

// 创建一个 ObjectAnimator
ObjectAnimator animator = ObjectAnimator.ofFloat(myButton, "translationX", 0f, 500f);
animator.setDuration(1000); // 设置时长
 
// 设置一个 AccelerateDecelerateInterpolator,让动画更自然
animator.setInterpolator(new AccelerateDecelerateInterpolator());
 
// 启动动画
animator.start();

通过选择不同的 Interpolator,你可以在不修改动画逻辑的情况下,轻松改变动画的视觉效果。

更新: 2025-08-21 09:48:18
原文: https://www.yuque.com/dongpozhouzi-mshe3/zhm85g/wmv54mg7uhpxh96x


相关笔记