嵌入 Rive 资源与控制器
加载 .riv 文件,并通过 Rive 画板和动画控制器驱动播放。
嵌入 Rive 资源与控制器 是 CoddyKit 上的免费 Flutter Mobile Development 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Flutter Mobile Development 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Flutter Mobile Development 课程共包含 4 节课。
本课时的部分内容尚未翻译,以英文显示。
What Rive Brings to Flutter
Rive is a real-time interactive design tool. Its runtime exports a compact binary file with the .riv extension that contains vector art, bones, timelines, and state machines.
- The
riveDart package renders these files natively on the GPU, so animations stay crisp at any resolution. - Unlike Lottie, Rive can run state machines driven by runtime inputs, making animations interactive rather than just playback-only.
In this lesson you will load a .riv asset, pick an artboard, and drive playback with an animation controller.
Adding the Dependency and Asset
First declare the package in pubspec.yaml and register the binary file under assets so Flutter bundles it.
- The version constraint targets Rive 0.13.x, which exposes the
RiveAnimationwidget and the controller APIs used below. - The asset path is relative to the project root; any file inside a declared folder is included.
dependencies:
flutter:
sdk: flutter
rive: ^0.13.1
flutter:
assets:
- assets/rive/vehicles.rivThe Simplest Embed
The fastest way to render a .riv file is the RiveAnimation.asset constructor. It loads, decodes, and plays the file's default animation automatically.
fitcontrols how the artboard scales inside the widget bounds, just likeBoxFitfor images.- This convenience widget is great for fire-and-forget visuals but gives you no handle to control playback.
import 'package:flutter/material.dart';
import 'package:rive/rive.dart';
class SplashLogo extends StatelessWidget {
const SplashLogo({super.key});
@override
Widget build(BuildContext context) {
return const RiveAnimation.asset(
'assets/rive/vehicles.riv',
fit: BoxFit.contain,
);
}
}Artboards: The Drawing Surface
A single .riv file can contain multiple artboards — independent canvases, each with its own art and animations. Think of them as separate scenes packed in one file.
- If you omit the name, Rive uses the file's default artboard.
- Pass
artboard:toRiveAnimation.assetto select a specific one by name.
Choosing the right artboard matters when a designer ships a shared library file with many components.
RiveAnimation.asset(
'assets/rive/vehicles.riv',
artboard: 'Truck',
fit: BoxFit.cover,
)Why You Need a Controller
To start, stop, or switch animations at runtime you must attach a controller. Rive offers two main kinds:
SimpleAnimation— plays one named timeline; toggle itsisActiveflag to pause/resume.StateMachineController— drives a state machine through typed inputs (booleans, numbers, triggers).
You create the controller in initState, pass it to the widget via the controllers: list, and dispose it when the widget is torn down.
Driving a SimpleAnimation
A SimpleAnimation targets one timeline by name. Setting isActive = false pauses it; setting it back to true resumes from where it stopped.
- Always keep the controller in a field so you can mutate it later.
- Pass it inside the
controllerslist; the widget wires it to the loaded artboard for you.
class DrivingCar extends StatefulWidget {
const DrivingCar({super.key});
@override
State<DrivingCar> createState() => _DrivingCarState();
}
class _DrivingCarState extends State<DrivingCar> {
late final SimpleAnimation _controller =
SimpleAnimation('idle', autoplay: true);
void _toggle() => _controller.isActive = !_controller.isActive;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: _toggle,
child: RiveAnimation.asset(
'assets/rive/vehicles.riv',
controllers: [_controller],
),
);
}
}State Machines and Inputs
State machines are where Rive shines. A StateMachineController exposes named inputs that you read off the controller after attaching it:
findInput<bool>('Hover')returns anSMIBoolyou flip with.value.findInput<double>('Speed')returns anSMINumber.findSMI('Tap')asSMITriggerfires a one-shot transition via.fire().
The factory StateMachineController.fromArtboard binds to a named state machine inside the artboard.
StateMachineController? _machine;
SMIBool? _pressed;
void _onRiveInit(Artboard artboard) {
final controller = StateMachineController.fromArtboard(
artboard,
'ButtonMachine',
);
if (controller != null) {
artboard.addController(controller);
_machine = controller;
_pressed = controller.findSMI('Pressed') as SMIBool?;
}
}Wiring the onInit Callback
When you need access to the Artboard instance — for example to attach a state machine — use the onInit callback of RiveAnimation.asset.
onInitfires once after the file is decoded and the artboard is ready.- This is the correct place to build a
StateMachineController, since the artboard does not exist before load completes.
RiveAnimation.asset(
'assets/rive/vehicles.riv',
artboard: 'Button',
stateMachines: const ['ButtonMachine'],
onInit: _onRiveInit,
)Loading the File Manually
For full control — caching, preloading, or rendering with a custom Rive widget — decode the file yourself with RiveFile.asset and pull the artboard from mainArtboard.
RiveFile.initialize()must run once before manual decoding (the widget constructors handle this for you).artboard.instance()gives you an isolated copy so two widgets can animate independently.
Future<Artboard> loadTruck() async {
await RiveFile.initialize();
final file = await RiveFile.asset('assets/rive/vehicles.riv');
final artboard = file.mainArtboard.instance();
final controller = SimpleAnimation('drive');
artboard.addController(controller);
return artboard;
}Always Dispose Controllers
Controllers hold references to the artboard and keep advancing the animation clock. Leaking them wastes frames and memory.
- Dispose every controller you created in
State.dispose(). - For state machines, also clear input references so they can be garbage collected.
The Rive widget removes controllers it owns automatically, but controllers you attach manually with addController are your responsibility.
@override
void dispose() {
_controller.dispose();
_machine?.dispose();
super.dispose();
}A Pure-Dart Playback Model
The Flutter widgets need a GPU and a host app, so they cannot run on a plain console. The logic of a simple animation controller, however, is just Dart and is easy to model and test in isolation.
Below is a tiny standalone simulation of how a SimpleAnimation's isActive flag gates time advancement — runnable on any Dart judge.
class FakeSimpleAnimation {
FakeSimpleAnimation(this.name, {this.isActive = true});
final String name;
bool isActive;
double _time = 0;
void advance(double dt) {
if (isActive) _time += dt;
}
double get time => _time;
}
void main() {
final anim = FakeSimpleAnimation('idle');
anim.advance(0.5);
anim.isActive = false;
anim.advance(0.5); // ignored while paused
anim.isActive = true;
anim.advance(0.25);
print('Elapsed: ${anim.time}s');
}Quick Check
You need to flip a boolean input on a Rive state machine when the user taps a button. Which approach is correct?
Recap
You can now embed and drive Rive in Flutter:
- Add
rivetopubspec.yamland register the.rivasset. RiveAnimation.assetrenders quickly; select a canvas withartboard:.- Attach a controller to control playback:
SimpleAnimationfor a single timeline,StateMachineControllerfor interactive inputs (SMIBool,SMINumber,SMITrigger). - Use
onInitto reach theArtboard, or load manually withRiveFile.assetfor full control. - Always dispose controllers you create to avoid leaks.
常见问题解答
「嵌入 Rive 资源与控制器」课时是免费的吗?
是的 — 「嵌入 Rive 资源与控制器」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Flutter Mobile Development 课程的其余内容,请升级到 CoddyKit PRO。 Flutter Mobile Development 课程共包含 4 节课。
「嵌入 Rive 资源与控制器」这节课中我会学到什么?
加载 .riv 文件,并通过 Rive 画板和动画控制器驱动播放。 你通过在浏览器中直接运行的动手代码来练习 Flutter Mobile Development,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Flutter Mobile Development 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Flutter Mobile Development 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「嵌入 Rive 资源与控制器」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Flutter Mobile Development 课中编写并运行代码吗?
能。每节 Flutter Mobile Development 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 嵌入 Rive 资源与控制器
- 状态机与输入驱动的运动
- Hero 转场与共享元素运动
- 交错动画与编排式 AnimationControllers