React Native Lottie——iOS 和 Android 一套代码动效
为什么适合跨端
React Native 本身就是"一套 JS 代码驱动两端原生渲染"——Lottie 完美契合这个定位:
- JS 层只负责传入 JSON 路径和播放参数。
- 原生层各自调用 lottie-ios / lottie-android 渲染引擎。
- 同一个 JSON 文件在两端表现一致,不需要 iOS 和 Android 分别适配。
安装
npm install lottie-react-native
# 同时需要 lottie-ios(iOS 原生依赖)
cd ios && pod install
如果用 Expo:
npx expo install lottie-react-native
基本用法
import React, { useRef, useEffect } from 'react';
import LottieView from 'lottie-react-native';
export default function LoadingScreen() {
const animationRef = useRef(null);
useEffect(() => {
animationRef.current?.play();
}, []);
return (
<LottieView
ref={animationRef}
source={require('./loading.json')}
autoPlay
loop
style={{ width: 200, height: 200 }}
/>
);
}
三种 source 方式
// 方式一:本地文件(require)
source={require('./loading.json')}
// 方式二:远程 URL
source={{ uri: '你的 CDN 托管地址' }}
// 方式三:内联 JSON 对象
source={{ /* 整个 JSON 对象 */ }}
// 方式四:dotLottie 文件
source={require('./button.lottie')}
播放控制
const animationRef = useRef(null);
// 播放
animationRef.current.play();
// 暂停
animationRef.current.pause();
// 停止
animationRef.current.reset();
// 跳到指定帧
animationRef.current.play(30, 60); // 从第 30 帧播到第 60 帧
// 倍速
<LottieView speed={1.5} />
// 循环次数
<LottieView loop={true} /> // 无限
<LottieView loop={3} /> // 3 次
<LottieView loop={false} /> // 单次
// 方向
<LottieView direction={-1} /> // 反向
<LottieView direction={1} /> // 正向
事件回调
<LottieView
source={require('./loading.json')}
loop={false}
onAnimationFinish={(isCancelled) => {
if (!isCancelled) {
console.log('动画播放完成');
}
}}
onLoopComplete={() => {
console.log('完成一次循环');
}}
/>
和纯 JS 动画的对比
| 维度 | Lottie React Native | Reanimated / 原生动画 API |
|---|---|---|
| 动画来源 | AE 导出 JSON | JS 里写 |
| 复杂度 | 设计师决定 | 开发者决定 |
| 文件体积 | 每个动画 10~50KB | 无额外文件 |
| 跨平台一致性 | 完全一致 | 可能有差异 |
| 定制化 | 有限(改 JSON 或 ValueCallback) | 完全自由 |
结论:品牌动效和设计师产出的动效用 Lottie,程序化的简单动效用 Reanimated。