Animated API 是 React Native 中内置的声明式动画库,能够在不增加 JavaScript 线程负载的情况下提供 60 FPS 的动画效果。根据 React Native 0.76(2025)的官方文档,Animated API 支持对所有类型的动画使用 useNativeDriver,通过 UI Manager 将计算转移到原生线程。该库允许创建复杂的动画链、交互式手势以及任何样式属性的插值——从透明度到变换。
要点概述
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 的基础是 Animated.Value,一个通过构造函数 new Animated.Value(0) 初始化的数值容器。每个 Animated.Value 存储一个初始数字并提供动画方法:timing、spring 和 decay。timing 方法使用 duration、delay 和 easing 参数创建线性或缓动动画。spring 方法使用 friction、tension 和 velocity 参数实现物理弹簧动画。decay 方法创建带惯性和衰减的动画——适用于滑动和滚动。所有方法返回一个可通过 start() 启动和 stop() 停止的 Animated.Composite 对象。动画在单独线程中执行:当 useNativeDriver = true 时,计算在原生 UI 线程中进行,JavaScript 线程保持空闲以处理事件和逻辑。
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 实现了基于胡克定律的弹簧动画模型。friction(摩擦力)参数控制振荡次数:friction 越高,停止越快。tension(张力)参数确定弹簧刚度:高 tension 加速运动。velocity 参数为惯性动画设置初始速度——对于跟随用户手势的动画至关重要。Animated.spring 没有固定持续时间——当速度和振幅达到阈值时动画结束。
Animated API 提供了四个内置动画组件:Animated.View、Animated.Text、Animated.ScrollView 和 Animated.Image。每个都是对相应原生组件的封装,支持在样式属性中传递 Animated.Value。Animated.View 是最常用的组件,接受与普通 View 相同的 props,但在 style 中支持动画值。Animated.Text 用于文本颜色或字母间距的动画。Animated.ScrollView 可让 scrollTo 和 contentOffset 动起来。Animated.Image 在加载图像时支持动画透明度和缩放。如果需要动画化其他组件,使用 Animated.createAnimatedComponent(MyComponent)。
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 可以转换为黄-橙-红色。
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.sequence、Animated.parallel 和 Animated.stagger。Animated.sequence 逐个启动动画:每个后续动画在前一个完成后开始。Animated.parallel 同时启动所有动画并共享一个完成回调。Animated.stagger 在每次启动之间带延迟启动动画——延迟启动,用于创建波浪效果。组合可以相互嵌套:来自 parallel 组的 sequence 或来自 sequence 的 parallel。这允许创建复杂的链:元素延迟出现动画、带 fade-in 的并行 slide-in、然后是 bounce 和 shake 的 sequence。
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 是一个动画配置选项,将整个动画逻辑从 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 是 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 是一种将原生事件(例如 gestureEvent)直接关联到 Animated.Value 的方法。与在回调中手动处理不同,Animated.event 在原生线程中同步工作,不需要为每个帧使用 JavaScript 桥接。这确保了即使在快速滑动时也能实现流畅的动画。Animated.event 接受映射数组,其中每个元素将事件字段关联到 Animated.Value。支持嵌套访问:Animated.event([{ nativeEvent: { translationX: xValue } }])。
让我们看三个在 React Native 项目中使用 Animated API 的实际示例。第一个示例——使用 opacity + translateY 序列的卡片出现动画。第二个示例——使用 spring 的按钮脉冲动画。第三个示例——使用 PanResponder 的交互式拖拽元素。所有示例均使用 useNativeDriver = true 并符合 React Native 0.76 的最佳实践。
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 }] }]
}
);
};
弹簧动画 利用物理弹簧模型产生自然的脉冲效果。设置低 friction(2-4)和高 tension(100-150)可产生自然衰减的柔和振荡。使用 Animated.loop 以 sequence 循环实现无限脉冲:scale → 1.2,scale → 1.0。脉冲应用于加载指示器、通知和强调按钮。
常见问题解答
Animated API 提供对动画的完全控制——持续时间、缓动、插值、组合。LayoutAnimation 是 React Native 内置的布局更改动画系统,具有自动插值功能。Animated API 需要显式声明 Animated.Value 和配置,但允许创建复杂链。LayoutAnimation 在状态更改时自动触发,使用更简单,但在灵活性上受限。
可以,width 和 height 可以通过 Animated API 进行动画,但不支持 useNativeDriver。布局属性的动画需要 JavaScript 驱动器,因为原生驱动器仅适用于非布局属性。使用 Animated.Value 配合 toValue 处理 width/height,并将 useNativeDriver 设置为 false。为获得更好的布局动画性能,请考虑使用 LayoutAnimation 或 react-native-reanimated。
调用 Animated.timing 或 Animated.spring 返回的动画对象上的 stop() 方法。示例:animRef.stop()。如果动画是 sequence 或 parallel 的一部分,stop() 会停止整个组。要检查状态,在 start(callback) 中使用回调——在强制停止时接收带有 finished: false 字段的 result 对象。
Animated.ValueXY 是用于二维坐标的容器,存储两个 Animated.Value:x 和 y。用于动画化元素在屏幕上的位置——拖拽、平移、滑动。ValueXY 提供了现成的 getLayout() 方法用于样式和 getTranslateTransform() 方法用于变换。在使用 PanResponder 时非常方便,因为需要同时动画化两个轴。
使用开发者菜单中的 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 或优化同时运行的动画数量。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。