You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 13:15:00