Rive动画加载缓慢并触发RangeError(index)问题求助
Rive动画加载慢+RangeError(index)问题解决
问题现象
创建空项目后使用给定代码加载Rive动画文件,运行时出现两个问题:
- 动画加载速度过慢
- 绘制阶段抛出
RangeError (index): Invalid value: Valid value range is empty: 0错误,错误关联组件为Rive
错误日志
The following RangeError was thrown during paint(): RangeError (index): Invalid value: Valid value range is empty: 0 The relevant error-causing widget was: Rive Rive:file:///Users/Downloads/new_animation/lib/views/animated_eyes_view.dart:347:26 When the exception was thrown, this was the stack: #0 List.[] (dart:core-patch/growable_array.dart:264:36) #1 Text._buildRenderStyles (package:rive/src/rive_core/text/text.dart:264:41) #2 Text.update (package:rive/src/rive_core/text/text.dart:558:7) #3 Artboard.updateComponents (package:rive/src/rive_core/artboard.dart:153:21) #4 Artboard.advance (package:rive/src/rive_core/artboard.dart:213:9) #5 RiveRenderObject.advance (package:rive/src/rive.dart:258:17) #6 RiveRenderBox.paint (package:rive/src/rive_render_box.dart:353:10) ...(省略后续栈信息)
原始代码
class _MyHomePageState extends State<MyHomePage> { Artboard? _riveArtBoard; StateMachineController? _controller; @override void initState() { _initArtBoard(); super.initState(); } Future<void> _initArtBoard() async { if (_riveArtBoard == null) { final riveByteData = await rootBundle.load("assets/rive/all_animations.riv"); RiveFile riveFile = RiveFile.import(riveByteData); _riveArtBoard = riveFile.mainArtboard; } _controller = StateMachineController.fromArtboard(_riveArtBoard!, 'buddy-V2') as StateMachineController; _controller!.isActive = true; _riveArtBoard!.addController(_controller!); if (mounted) { setState(() {}); } } @override void dispose() { _controller?.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Rive Animation"), ), backgroundColor: Colors.white, body: _riveArtBoard == null ? const Center( child: CupertinoActivityIndicator( color: Colors.black, ), ) : Rive( artboard: _riveArtBoard!, fit: BoxFit.contain, useArtboardSize: true, ), ); } }
解决方案
1. 修复RangeError错误
从错误栈可以看出,问题出在Rive的Text组件渲染时访问了空列表的索引0,原因通常是Rive文件中文本元素未关联有效字体,或SDK版本存在bug。解决步骤:
- 打开Rive编辑器,检查动画中所有文本元素,确保每个文本都指定了有效字体,无缺失样式配置
- 将
rive依赖升级到最新稳定版(修改pubspec.yaml版本后执行flutter pub get) - 在初始化代码中添加错误捕获,避免崩溃:
Future<void> _initArtBoard() async { if (_riveArtBoard == null) { try { final riveByteData = await rootBundle.load("assets/rive/all_animations.riv"); RiveFile riveFile = RiveFile.import(riveByteData); _riveArtBoard = riveFile.mainArtboard; _controller = StateMachineController.fromArtboard(_riveArtBoard!, 'buddy-V2'); if (_controller != null) { _controller!.isActive = true; _riveArtBoard!.addController(_controller!); } } catch (e) { debugPrint("Rive初始化错误: $e"); } } if (mounted) { setState(() {}); } }
2. 优化加载速度
- 预加载资源:在App启动时提前加载Rive文件,而非页面initState中加载:
void main() async { WidgetsFlutterBinding.ensureInitialized(); // 预加载Rive资源 await rootBundle.load("assets/rive/all_animations.riv"); runApp(const MyApp()); }
- 拆分大文件:若
all_animations.riv包含多个动画,拆分出当前页面需要的单独文件,减少加载体积 - 使用FutureBuilder优化加载状态:替换原有状态判断,让逻辑更清晰:
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("Rive Animation")), backgroundColor: Colors.white, body: FutureBuilder<void>( future: _initArtBoard(), builder: (context, snapshot) { if (snapshot.connectionState != ConnectionState.done) { return const Center(child: CupertinoActivityIndicator(color: Colors.black)); } if (_riveArtBoard == null) { return const Center(child: Text("动画加载失败")); } return Rive( artboard: _riveArtBoard!, fit: BoxFit.contain, useArtboardSize: true, ); }, ), ); }
内容的提问来源于stack exchange,提问作者Sheetal Savani
相关产品推荐
相关产品推荐

