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

Flutter应用点击Rive动画菜单按钮侧边栏无响应问题求助

问题排查与修复方案

核心问题分析

你的代码存在几个关键问题导致点击无反应、侧边栏不弹出:

  1. 缺少侧边栏UI实现:仅定义了侧边栏动画_sidebarAnim,但没有在页面中添加对应的侧边栏Widget,动画没有作用对象
  2. Rive状态初始化逻辑错误:初始设置_menuBtn.value = true,导致首次点击时的动画逻辑反向
  3. onMenuPress中动画调用逻辑问题:_animationController是late非空变量,无需使用?调用;且动画执行顺序与状态切换顺序不合理
  4. AppBar中AnimatedBuilder无实际内容:该组件没有传入child,无法看到动画效果

分步修复代码

1. 添加侧边栏UI与动画绑定

在Scaffold的body中添加自定义侧边栏,通过_sidebarAnim控制其显示/隐藏:

@override
Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: Colors.white,
    appBar: AppBar(
      // 保留原AppBar代码
      automaticallyImplyLeading: false,
      backgroundColor: Colors.black,
      actions: <Widget>[
        GestureDetector(
          onTap: onMenuPress,
          child: Container(
            width: 70,
            height: 70,
            margin: const EdgeInsets.all(16),
            decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(70 / 2),
                boxShadow: [
                  BoxShadow(
                      color: RiveAppTheme.shadow.withOpacity(0.2),
                      blurRadius: 5,
                      offset: const Offset(0, 5))
                ]),
            child: RiveAnimation.asset(
              '/Users/lilianasanda/influfit/assets/rive/menu_button.riv',
              stateMachines: const ["State Machine"],
              animations: const ["open", "close"],
              onInit: _onMenuIconInit,
            ),
          ),
        )
      ],
    ),
    body: Stack(
      children: [
        // 主内容区域
        tabItems[_selectedIndex],
        // 侧边栏
        AnimatedBuilder(
          animation: _sidebarAnim,
          builder: (context, child) {
            return Transform.translate(
              offset: Offset(-MediaQuery.of(context).size.width * (1 - _sidebarAnim.value), 0),
              child: child,
            );
          },
          child: Container(
            width: MediaQuery.of(context).size.width * 0.8,
            color: Colors.grey[100],
            child: Column(
              children: [
                const SizedBox(height: 80),
                ListTile(title: const Text("菜单1")),
                ListTile(title: const Text("菜单2")),
                ListTile(title: const Text("菜单3")),
              ],
            ),
          ),
        ),
        // 遮罩层:侧边栏弹出时添加半透明遮罩,点击可关闭
        if (_sidebarAnim.value > 0)
          GestureDetector(
            onTap: onMenuPress,
            child: Container(
              color: Colors.black.withOpacity(_sidebarAnim.value * 0.5),
            ),
          ),
      ],
    ),
  );
}

2. 修正Rive初始化逻辑

将_onMenuIconInit中的初始状态改为false,对应侧边栏默认隐藏:

void _onMenuIconInit(Artboard artboard) {
  final controller = StateMachineController.fromArtboard(artboard, "State Machine");
  artboard.addController(controller!);
  _menuBtn = controller.findInput<bool>("isOpen") as SMIBool;
  // 默认侧边栏隐藏,所以初始值为false
  _menuBtn.value = false;
}

3. 修复onMenuPress逻辑

去掉_animationController的可空调用,调整状态切换与动画执行顺序:

void onMenuPress() {
  // 先切换Rive按钮状态
  _menuBtn.value = !_menuBtn.value;
  // 根据新状态执行动画
  if (_menuBtn.value) {
    final springAnim = SpringSimulation(springDesc, 0, 1, 0);
    _animationController.animateWith(springAnim);
  } else {
    _animationController.reverse();
  }
}

额外注意事项

  • 确保Rive动画文件的stateMachine名称和输入参数isOpen与你的Rive源文件完全一致
  • 侧边栏的宽度、样式可根据需求自定义调整
  • 遮罩层的点击关闭逻辑可根据交互需求选择保留或移除

内容的提问来源于stack exchange,提问作者sanda17

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 22:32:09