Animated API:简介、库的功能与工作原理

作者: IT Sectr 发布日期: 2026-07-06 阅读时间: 8 分钟

Animated API 是 React Native 中内置的声明式动画库,能够在不增加 JavaScript 线程负载的情况下提供 60 FPS 的动画效果。根据 React Native 0.76(2025)的官方文档,Animated API 支持对所有类型的动画使用 useNativeDriver,通过 UI Manager 将计算转移到原生线程。该库允许创建复杂的动画链、交互式手势以及任何样式属性的插值——从透明度到变换。

要点概述

  • Animated API — 支持原生驱动器的 React Native 声明式动画库
  • Animated.Value — 存储数值并将组件订阅到变化的基本元素
  • useNativeDriver — 将动画转移到原生线程以实现 60 FPS 无卡顿的选项
  • 插值 — 将数值范围转换为颜色、角度、坐标和比例的机制
  • 组合 — 通过 sequence、parallel 和 stagger 实现的顺序、并行和链式动画

React Native 中的 Animated API 是什么

Animated API 是一个声明式动画库,内置于 React Native 核心,旨在为移动应用创建流畅、高性能的动画。与 web 开发中的 CSS 动画不同,Animated API 通过 JavaScript 桥接或原生驱动器直接与原生 UI 线程协作。该库围绕 Animated.Value 概念构建——这是一个存储数值并自动将所有依赖组件订阅到变化的容器。当通过 Animated.timing 或 Animated.spring 更改值时,库计算中间状态而无需重新渲染 React 组件,这对于保持 60 FPS 至关重要。Animated API 支持所有样式属性,包括 transform、opacity、width、height、top、left 和 backgroundColor。React Native 官方文档推荐将 Animated API 用于所有需要高性能和跨平台可预测行为的动画场景。

Animated API 的工作原理:Value、timing 和 spring

Animated API 的基础是 Animated.Value,一个通过构造函数 new Animated.Value(0) 初始化的数值容器。每个 Animated.Value 存储一个初始数字并提供动画方法:timingspringdecay。timing 方法使用 duration、delay 和 easing 参数创建线性或缓动动画。spring 方法使用 friction、tension 和 velocity 参数实现物理弹簧动画。decay 方法创建带惯性和衰减的动画——适用于滑动和滚动。所有方法返回一个可通过 start() 启动和 stop() 停止的 Animated.Composite 对象。动画在单独线程中执行:当 useNativeDriver = true 时,计算在原生 UI 线程中进行,JavaScript 线程保持空闲以处理事件和逻辑。

Animated.timing:持续时间和缓动配置

Animated.timing 是基本的可控持续时间动画方法。接受配置:toValue、duration(默认 500ms)、easing(默认 Easing.linear)和 delay。Easing 模块中的缓动函数允许非线性加速:Easing.bezier、Easing.elastic、Easing.bounce。对于匀速动画使用 Easing.linear,对于自然加速使用 Easing.inOut。重要提示:Animated.timing 保证动画在指定时间内精确到达 toValue,无论设备负载如何。

Animated.spring:物理动画

Animated.spring 实现了基于胡克定律的弹簧动画模型。friction(摩擦力)参数控制振荡次数:friction 越高,停止越快。tension(张力)参数确定弹簧刚度:高 tension 加速运动。velocity 参数为惯性动画设置初始速度——对于跟随用户手势的动画至关重要。Animated.spring 没有固定持续时间——当速度和振幅达到阈值时动画结束。

Animated.View、Animated.Text 及其他组件

Animated API 提供了四个内置动画组件:Animated.ViewAnimated.TextAnimated.ScrollViewAnimated.Image。每个都是对相应原生组件的封装,支持在样式属性中传递 Animated.Value。Animated.View 是最常用的组件,接受与普通 View 相同的 props,但在 style 中支持动画值。Animated.Text 用于文本颜色或字母间距的动画。Animated.ScrollView 可让 scrollTo 和 contentOffset 动起来。Animated.Image 在加载图像时支持动画透明度和缩放。如果需要动画化其他组件,使用 Animated.createAnimatedComponent(MyComponent)。

js
import React from 'react';
import { Animated, View, Button } from 'react-native';

const FadeInView = () => {
  const opacity = useRef(new Animated.Value(0)).current;

  const fadeIn = () => {
    Animated.timing(opacity, {
      toValue: 1,
      duration: 1000,
      useNativeDriver: true,
    }).start();
  };

  return (
    View
      Animated.View { style: [{ opacity }] }
      Button title="Fade In" onPress={fadeIn}
  );
};

插值系统:从数字到颜色和变换

插值 是将 Animated.Value 的输入数值范围转换为其他类型输出值的机制。interpolate 方法接受带有 inputRange(输入值数组)和 outputRange(输出值数组)的配置。outputRange 类型:数字(坐标、透明度)、字符串(带 'deg' 的旋转角度)、十六进制颜色('#ff0000')、变换对象。插值支持 easing 和 extrapolate——超出指定范围的行为(clamp、extend、identity)。例如,在拖拽手势中,可以将手指从 0 到 200 的位置转换为从 1 到 0 的透明度,在滑动时创建淡出效果。插值系统允许创建复杂的多步动画:值 0-0.5-1.0 可以转换为黄-橙-红色。

js
const spinValue = new Animated.Value(0);

Animated.timing(spinValue, {
  toValue: 1,
  duration: 3000,
  easing: Easing.linear,
  useNativeDriver: true,
}).start();

const spin = spinValue.interpolate({
  inputRange: [0, 1],
  outputRange: ['0deg', '360deg'],
});

动画组合:顺序与并行

Animated API 支持三种动画组合模式:Animated.sequenceAnimated.parallelAnimated.stagger。Animated.sequence 逐个启动动画:每个后续动画在前一个完成后开始。Animated.parallel 同时启动所有动画并共享一个完成回调。Animated.stagger 在每次启动之间带延迟启动动画——延迟启动,用于创建波浪效果。组合可以相互嵌套:来自 parallel 组的 sequence 或来自 sequence 的 parallel。这允许创建复杂的链:元素延迟出现动画、带 fade-in 的并行 slide-in、然后是 bounce 和 shake 的 sequence。

js
Animated.sequence([
  Animated.timing(fadeAnim, {
    toValue: 1,
    duration: 500,
    useNativeDriver: true,
  }),
  Animated.parallel([
    Animated.timing(scaleAnim, {
      toValue: 1.1,
      duration: 200,
      useNativeDriver: true,
    }),
    Animated.spring(colorAnim, {
      toValue: 1,
      friction: 4,
      useNativeDriver: true,
    }),
  ]),
]).start();

useNativeDriver 与动画性能

useNativeDriver 是一个动画配置选项,将整个动画逻辑从 JavaScript 线程转移到原生 UI 线程。没有 useNativeDriver 时,动画通过 JavaScript 桥接执行:每次值更改都会发送到原生线程,当 JS 线程因异步操作而负载时会引发延迟。使用 useNativeDriver = true 时,Animated.Value 直接在原生侧更新,JavaScript 线程保持空闲以处理事件、API 请求和 React 协调。限制:useNativeDriver 仅支持非布局属性——opacity、transform、backgroundColor(通过 PlatformColor)。对于布局属性(width、height、top、left)需要 NativeAnimatedModule 或 LayoutAnimation。根据 React Native 0.76,除基于布局的属性外,所有动画属性都通过原生驱动器支持。useNativeDriver 模式推荐用于所有可能的动画——它将 FPS 从 30-40 提升至稳定的 60。

手势动画:PanResponder 与 Gesture Handler

PanResponder 是 React Native 内置的手势处理系统,与 Animated API 完美集成。PanResponder 提供 onPanResponderMove 和 onPanResponderRelease 回调,可以根据手指位置更新 Animated.Value。对于更复杂的手势——滑动、捏合、旋转——使用 react-native-gesture-handler 库,它与动画同步工作,甚至在多指手势下也能确保 60 FPS。Gesture Handler 提供了 Animated.event——一种无需手动处理回调即可直接连接手势与 Animated.Value 的方法。Gesture Handler + Animated API 的组合是 React Native 应用中交互式动画的行业标准。

Animated.event:将手势绑定到值

Animated.event 是一种将原生事件(例如 gestureEvent)直接关联到 Animated.Value 的方法。与在回调中手动处理不同,Animated.event 在原生线程中同步工作,不需要为每个帧使用 JavaScript 桥接。这确保了即使在快速滑动时也能实现流畅的动画。Animated.event 接受映射数组,其中每个元素将事件字段关联到 Animated.Value。支持嵌套访问:Animated.event([{ nativeEvent: { translationX: xValue } }])。

Animated API 代码示例

让我们看三个在 React Native 项目中使用 Animated API 的实际示例。第一个示例——使用 opacity + translateY 序列的卡片出现动画。第二个示例——使用 spring 的按钮脉冲动画。第三个示例——使用 PanResponder 的交互式拖拽元素。所有示例均使用 useNativeDriver = true 并符合 React Native 0.76 的最佳实践。

js
const CardWithAnimation = () => {
  const anim = useRef(new Animated.Value(0)).current;

  React.useEffect(() => {
    Animated.spring(anim, {
      toValue: 1,
      friction: 6,
      tension: 40,
      useNativeDriver: true,
    }).start();
  }, []);

  const translateY = anim.interpolate({
    inputRange: [0, 1],
    outputRange: [50, 0],
  });

  return (
    Animated.View {
      style: [{ opacity: anim, transform: [{ translateY }] }]
    }
  );
};

通过 spring 实现的脉冲动画

弹簧动画 利用物理弹簧模型产生自然的脉冲效果。设置低 friction(2-4)和高 tension(100-150)可产生自然衰减的柔和振荡。使用 Animated.loop 以 sequence 循环实现无限脉冲:scale → 1.2,scale → 1.0。脉冲应用于加载指示器、通知和强调按钮。

常见问题解答

Animated API 与 LayoutAnimation 有何不同?

Animated API 提供对动画的完全控制——持续时间、缓动、插值、组合。LayoutAnimation 是 React Native 内置的布局更改动画系统,具有自动插值功能。Animated API 需要显式声明 Animated.Value 和配置,但允许创建复杂链。LayoutAnimation 在状态更改时自动触发,使用更简单,但在灵活性上受限。

能否通过 Animated API 动画化 width 和 height?

可以,width 和 height 可以通过 Animated API 进行动画,但不支持 useNativeDriver。布局属性的动画需要 JavaScript 驱动器,因为原生驱动器仅适用于非布局属性。使用 Animated.Value 配合 toValue 处理 width/height,并将 useNativeDriver 设置为 false。为获得更好的布局动画性能,请考虑使用 LayoutAnimation 或 react-native-reanimated。

如何停止 Animated API 中的当前动画?

调用 Animated.timing 或 Animated.spring 返回的动画对象上的 stop() 方法。示例:animRef.stop()。如果动画是 sequence 或 parallel 的一部分,stop() 会停止整个组。要检查状态,在 start(callback) 中使用回调——在强制停止时接收带有 finished: false 字段的 result 对象。

什么是 Animated.ValueXY 以及何时使用它?

Animated.ValueXY 是用于二维坐标的容器,存储两个 Animated.Value:x 和 y。用于动画化元素在屏幕上的位置——拖拽、平移、滑动。ValueXY 提供了现成的 getLayout() 方法用于样式和 getTranslateTransform() 方法用于变换。在使用 PanResponder 时非常方便,因为需要同时动画化两个轴。

如何在 React Native 中测量动画 FPS?

使用开发者菜单中的 React Native Performance Monitor(Cmd+D / Cmd+M)。启用 FPS Monitor——它将实时显示 UI FPS 和 JS FPS。对于程序化测量,使用 import { InteractionManager } 来跟踪动画的完成。稳定的 60 UI FPS 和 50+ JS FPS 是优化良好的动画指标。如果 UI FPS 降至 30 以下,请关闭 useNativeDriver 或优化同时运行的动画数量。

总结

  • Animated API — 支持原生驱动器的 React Native 声明式动画库,实现 60 FPS
  • Animated.Value — 基本数值容器,将组件订阅到变化而无需重新渲染
  • Timing、Spring、Decay — 三种动画模式:时间控制、物理弹簧和惯性
  • 插值 将数值范围转换为颜色、角度、坐标——复杂视觉效果的基础
  • 组合 通过 sequence、parallel 和 stagger 允许创建多步动画链
  • useNativeDriver 对性能至关重要——将计算转移到原生 UI 线程
  • PanResponder 和 Gesture Handler 与 Animated API 集成用于交互式手势动画
  • 使用 Animated.event 将手势直接绑定到值,无需 JavaScript 桥接

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读