React Native
🚀 新版 Rive React Native 运行时现已可用! 基于 Nitro 构建,性能更优,React Native 集成更好。
快速入门:
迁移路线图:
我们正在积极收集反馈以改进新版运行时。欢迎分享您的使用体验并报告问题。
概述
本指南介绍如何使用 Rive React Native 运行时。新版运行时的源代码位于其 GitHub 仓库。
新版运行时(推荐)
系统要求
- React Native:0.78 或更高版本(建议 0.79+,可获得更好的 Android 错误信息)
- Expo SDK:53 或更高版本(Expo 用户)
- iOS:15.1 或更高版本
- Android:SDK 24(Android 7.0)或更高版本
- Xcode:16.4 或更高版本
- JDK:17 或更高版本
- Nitro Modules:0.25.2 或更高版本
快速入门
按照以下步骤快速上手 Rive React Native 运行时。
安装依赖
npm install @rive-app/react-native react-native-nitro-modules
# 或使用 Yarn
yarn add @rive-app/react-native react-native-nitro-modules
react-native-nitro-modules是必需的,因为此库依赖于 Nitro Modules。
设置
导入必要的组件并为后续步骤定义样式。
import {
RiveView,
useRive,
useRiveFile,
useRiveNumber,
useRiveTrigger,
useViewModelInstance,
Fit,
} from '@rive-app/react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
rive: {
width: '100%',
height: 400,
},
});
Rive 文件和组件
RiveView 组件用于显示 Rive 图形。它需要一个属性:file,即 RiveFile 对象。
使用 useRiveFile hook 加载 riv 文件并创建 RiveFile 对象。该对象可以缓存并在多个组件间复用。
export default function QuickStart() {
const { riveFile } = useRiveFile(
require('path/to/quick_start.riv')
);
return (
<View style={styles.container}>
{riveFile && <RiveView file={riveFile} style={styles.rive} />}
</View>
);
}
延伸阅读:
- 属性 —
RiveView可用的视图属性 - 加载 Rive 文件 — 如何在应用中加载 Rive 文件
- 缓存 Rive 文件 — 缓存 Rive 文件以获得更好性能
布局
配置图形在其容器内的适配方式。
在此示例中,我们将 fit 设置为 Layout,这将自动调整画板大小以匹配视图尺寸。这非常适合使用布局构建的响应式 Rive 图形。
<RiveView
file={riveFile}
style={styles.rive}
fit={Fit.Layout}
/>
延伸阅读:
- 运行时布局 — 控制 Rive 图形在其容器内的适配和对齐方式
视图引用
使用 useRive() hook 访问 Rive 视图引用以进行编程控制。
export default function QuickStart() {
const { riveFile } = useRiveFile(
require('path/to/quick_start.riv')
);
const { riveViewRef, setHybridRef } = useRive();
return (
<View style={styles.container}>
{riveFile && (
<RiveView
hybridRef={setHybridRef}
file={riveFile}
fit={Fit.Layout}
style={styles.rive}
/>
)}
</View>
);
}
延伸阅读:
- 视图方法 — 查看所有可用的视图引用方法
- Hybrid Views — 了解更多 Nitro Hybrid Views
数据绑定
使用 useViewModelInstance hook 手动创建视图模型实例,并将其传递给视图。
这种方式允许您在视图加载之前在 onInit 回调中设置初始属性值,并将 ViewModelInstance 与 RiveView 解耦。
export default function QuickStart() {
const { riveFile } = useRiveFile(
require('path/to/quick_start.riv')
);
const { riveViewRef, setHybridRef } = useRive();
const { instance: viewModelInstance, isLoading, error } = useViewModelInstance(riveFile, { async: true,
onInit: (vmi) => vmi.numberProperty('health')!.set(20),
});
return (
<View style={styles.container}>
{riveFile && viewModelInstance && (
<RiveView
hybridRef={setHybridRef}
file={riveFile}
fit={Fit.Layout}
style={styles.rive}
dataBind={viewModelInstance}
/>
)}
</View>
);
}
使用视图模型属性 hooks 来更新和监听属性变化。
export default function QuickStart() {
const { riveFile } = useRiveFile(
require('path/to/quick_start.riv')
);
const { riveViewRef, setHybridRef } = useRive();
const { instance: viewModelInstance, isLoading, error } = useViewModelInstance(riveFile, { async: true,
onInit: (vmi) => vmi.numberProperty('health')!.set(20),
});
const { value: health, setValue: setHealth } = useRiveNumber(
'health',
viewModelInstance
);
console.log('health', health);
const { trigger: gameOverTrigger } = useRiveTrigger(
'gameOver',
viewModelInstance,
{ onTrigger: () => console.log('Game Over Triggered') }
);
const handleTakeDamage = () => {
setHealth((h) => (h ?? 0) - 7);
riveViewRef!.playIfNeeded();
};
const handleMaxHealth = () => {
setHealth(100);
riveViewRef!.playIfNeeded();
};
const handleGameOver = () => {
setHealth(0);
gameOverTrigger();
riveViewRef!.playIfNeeded();
};
return (
<View style={styles.container}>
{riveFile && viewModelInstance && (
<RiveView
hybridRef={setHybridRef}
file={riveFile}
fit={Fit.Layout}
style={styles.rive}
dataBind={viewModelInstance}
/>
)}
<Button onPress={handleTakeDamage} title="Take Damage" />
<Button onPress={handleMaxHealth} title="Max Health" />
<Button onPress={handleGameOver} title="Game Over" />
</View>
);
}
⚠️ 我们调用
playIfNeeded来强制状态机播放。在某些情况下,如果图形中没有活跃的时间线,状态机可能会处于 settled 状态。这是一个临时解决方法。未来这将自动处理。
延伸阅读:
- 数据绑定 — 查看运行时数据绑定文档了解更多信息
参见我们的示例应用了解更多用法示例。
核心组件
RiveView
渲染 Rive 内容的组件:
<RiveView
file={riveFile}
/>
useRiveFile
用于从 URL 或本地源加载 Rive 文件的 hook:
const { riveFile } = useRiveFile(
'https://cdn.rive.app/animations/vehicles.riv'
);
// 或
// const { riveFile } = useRiveFile(require('./assets/graphic.riv'));
参见加载 Rive 文件和缓存 Rive 文件了解更多信息。
useRive
用于访问 Rive 视图引用以进行编程控制的 hook:
const { riveViewRef, setHybridRef } = useRive();
<RiveView
hybridRef={setHybridRef}
file={riveFile}
/>
这是一个 Nitro Hybrid View。参见可用的视图引用方法。
useViewModelInstance
从 RiveFile、ViewModel 或 RiveViewRef 创建视图模型实例的 hook。
传入 async: true 以选择异步实例创建——该标志表示您的组件会处理加载状态。hook 返回 { instance, isLoading, error },且实例在首次渲染时不可用。这为新的运行时实现做好了准备——在该实现中,创建实例是一个异步操作。
// 从 RiveFile — 默认画板的 ViewModel,默认实例
const { instance, isLoading, error } = useViewModelInstance(riveFile, { async: true });
// 从 RiveFile — 指定画板或 ViewModel 名称(互斥)
const { instance, isLoading, error } = useViewModelInstance(riveFile, { async: true, artboardName: 'MainArtboard' });
const { instance, isLoading, error } = useViewModelInstance(riveFile, { async: true, viewModelName: 'Settings' });
// instanceName 可与上述任意选项组合以选择特定实例
const { instance, isLoading, error } = useViewModelInstance(riveFile, { async: true, instanceName: 'PersonInstance' });
const { instance, isLoading, error } = useViewModelInstance(riveFile, { async: true, viewModelName: 'Settings', instanceName: 'UserSettings' });
// 从 ViewModel 对象
const { instance: namedInstance, isLoading, error } = useViewModelInstance(viewModel, { async: true, name: 'My Instance' });
const { instance: newInstance, isLoading, error } = useViewModelInstance(viewModel, { async: true, useNew: true });
// 使用 required: true(解析为 null 时抛出异常,需配合 Error Boundary 使用)
const { instance, isLoading, error } = useViewModelInstance(riveFile, { async: true, required: true });
// 使用 onInit 在实例暴露或绑定之前设置初始值
const { instance, isLoading, error } = useViewModelInstance(riveFile, {
async: true,
onInit: (vmi) => {
vmi.numberProperty('health')!.set(100);
},
});
async: true在@rive-app/[email protected]及更高版本中可用。同步创建路径已弃用,将在未来版本中移除。
在 RiveView 中传递 dataBind 属性:
return (
<RiveView
file={riveFile}
dataBind={instance}
/>
);
您也可以从 RiveViewRef 获取自动绑定的实例——该 hook 会等待视图的自动绑定实例变为可用:
import { useRive, useViewModelInstance } from '@rive-app/react-native';
const { riveViewRef, setHybridRef } = useRive();
const { instance, isLoading, error } = useViewModelInstance(riveViewRef, { async: true });
参见运行时数据绑定文档了解更多信息。
资源
旧版运行时
⚠️ 旧版运行时仍然受支持,但我们建议迁移到新版运行时以获得更好的性能和功能。
本指南介绍如何使用旧版 React Native 运行时库。源代码位于 其 GitHub 仓库。该库包含一个 API,让 React Native 应用可以轻松集成 Rive 资源。
iOS 最低版本要求为 14.0。
参见我们的文档了解如何将 Rive 添加到 Expo 应用。
快速入门
按照以下步骤快速将 Rive 集成到您的 React Native 应用中。
安装依赖
npm install rive-react-native
# 或使用 Yarn
yarn add rive-react-native
iOS - Pod Install
进入 ios 文件夹并运行 pod install(如果要部署到 iOS)。
如果在此步骤遇到问题,可能需要将
ios部署目标版本至少提升到14.0。您可以在ios/文件夹的Podfile中找到此版本。
Android - 设置 Kotlin 依赖解析
此步骤可能是可选的——但如果您的 React Native 项目中的 Android 设置没有 Kotlin v1.8.0+,在构建项目时可能会遇到重复类的问题。为解决此问题,按照 Kotlin 文档的建议,在应用的 build.gradle 文件中添加以下依赖来处理版本对齐:
dependencies {
implementation platform('org.jetbrains.kotlin:kotlin-bom:1.8.0')
...
}
添加 Rive 组件
import Rive from 'rive-react-native';
function App() {
return <Rive
url="https://public.rive.app/community/runtime-files/2195-4346-avatar-pack-use-case.riv"
artboardName="Avatar 1"
stateMachineName="avatar"
style={{width: 400, height: 400}}
/>;
}
故障排查
Windows 上 Android 构建失败(CMake 长路径错误)
在 Windows 上,Android 构建可能会因为路径超过 Windows MAX_PATH(260 个字符)限制而失败,错误类似:ninja: error: mkdir(CMakeFiles/rive.dir/...): No such file or directory。这是使用 CMake 的 React Native 库中较常见的已知问题。
解决方法是在构建前将 CMAKE_VERSION 环境变量设置为较新的 CMake 版本 ,例如 3.31.6:
set CMAKE_VERSION=3.31.6
完整的 Windows 构建设置请参考 Reanimated 的 Windows 构建文档。