如何实现Rive stateMachine动画跟随TextField输入内容的效果?
实现跟随TextField文本变化的Rive动画方案
前置准备
- 先在
pubspec.yaml中添加Rive依赖:
dependencies: flutter: sdk: flutter rive: ^0.11.17 # 可替换为最新稳定版本
- 将你准备好的Rive文件放到项目
assets/rives/目录下,并在pubspec.yaml中配置资源路径:
flutter: assets: - assets/rives/eyeMovement.riv
核心实现逻辑
你使用的Rive文件已经预设了控制眼球移动的状态机数值输入参数,只需要在Flutter侧监听TextField的文本变化,将文本长度/光标位置换算成对应的参数值传给Rive状态机即可。
完整示例代码如下:
import 'package:flutter/material.dart'; import 'package:rive/rive.dart'; class FollowTextRiveDemo extends StatefulWidget { const FollowTextRiveDemo({super.key}); @override State<FollowTextRiveDemo> createState() => _FollowTextRiveDemoState(); } class _FollowTextRiveDemoState extends State<FollowTextRiveDemo> { // 文本编辑控制器,用于监听输入变化 final TextEditingController _textController = TextEditingController(); // Rive相关控制器 StateMachineController? _stateMachineController; // Rive状态机的数值输入项,对应控制眼球X轴移动的参数 SMI<double>? _eyeMoveInput; // 输入框最大可输入长度,用于计算偏移比例,可根据需求调整 final int _maxInputLength = 20; @override void initState() { super.initState(); // 监听文本输入变化 _textController.addListener(_syncInputToRive); } // Rive文件加载完成的回调 void _onRiveInit(Artboard artboard) { // 从Rive文件中获取状态机,注意状态机名称要和你Rive文件里的命名一致 _stateMachineController = StateMachineController.fromArtboard( artboard, 'State Machine 1', // 请替换为你的Rive文件里实际的状态机名称 ); if (_stateMachineController != null) { artboard.addController(_stateMachineController!); // 获取状态机中控制眼球移动的输入参数,参数名要和Rive文件里的命名一致 _eyeMoveInput = _stateMachineController!.findInput<double>('eyeX'); } } // 同步输入变化到Rive动画 void _syncInputToRive() { if (_eyeMoveInput == null) return; // 计算当前输入长度占最大长度的比例,换算成Rive参数对应的数值范围 // 这里的-4到4是Rive文件里预设的eyeX参数的取值范围,可根据实际效果调整 final moveValue = (_textController.text.length / _maxInputLength) * 8 - 4; // 限制数值范围,避免眼球超出可视区域 _eyeMoveInput!.value = moveValue.clamp(-4, 4); } @override void dispose() { _textController.dispose(); _stateMachineController?.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: Padding( padding: const EdgeInsets.symmetric(horizontal: 24), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // Rive动画组件 SizedBox( height: 120, child: RiveAnimation.asset( 'assets/rives/eyeMovement.riv', onInit: _onRiveInit, ), ), const SizedBox(height: 32), // 输入框 TextField( controller: _textController, maxLength: _maxInputLength, decoration: const InputDecoration( hintText: '输入内容查看动画效果', border: OutlineInputBorder(), ), ) ], ), ), ); } }
调整适配说明
- 如果Rive文件里的状态机名称、控制参数名称和示例中不一致,需要替换成你实际的命名
- 眼球移动的数值范围、和输入长度的换算比例可以根据实际视觉效果调整
- 如果需要实现Y轴方向的跟随效果,只需要在Rive状态机中添加对应的Y轴控制参数,在Flutter侧监听光标垂直位置同步数值即可
内容的提问来源于stack exchange,提问作者Md. Yeasin Sheikh
相关产品推荐
相关产品推荐

