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

Flutter 关闭modal bottom sheet后AppBar上AnimatedIcon无法回退问题求助

问题修复方案

问题根因

  • showModalBottomSheet方法返回Future对象,用户手动关闭底部弹窗时不会触发你写的图标点击逻辑,你没有监听这个关闭事件来同步动画状态
  • 现有代码未同步修改isPlaying状态变量,导致动画状态判断逻辑失效
  • reverseDuration参数单位填写错误,误写为微秒(microseconds),实际应为毫秒(milliseconds),会导致反向动画无过渡效果

修复后完整代码

import 'package:flutter/material.dart';

class TabsScreen extends StatefulWidget {
  const TabsScreen({Key? key}) : super(key: key);

  @override
  _TabsScreenState createState() => _TabsScreenState();
}

class _TabsScreenState extends State<TabsScreen>
    with SingleTickerProviderStateMixin {
  late AnimationController _animationController;
  bool isPlaying = false;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
        vsync: this,
        duration: const Duration(milliseconds: 450),
        // 修正单位为毫秒
        reverseDuration: const Duration(milliseconds: 450));
  }

  @override
  void dispose() {
    // 释放动画控制器避免内存泄漏
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('title'),
          actions: <Widget>[
            IconButton(
                icon: AnimatedIcon(
                  icon: AnimatedIcons.menu_close,
                  progress: _animationController,
                ),
                onPressed: () async {
                  if (!isPlaying) {
                    // 正向执行动画,切换为关闭图标
                    _animationController.forward();
                    setState(() => isPlaying = true);
                    // 等待底部弹窗关闭回调
                    await showModalBottomSheet(
                      context: context,
                      builder: (context) => Container(
                        color: Colors.deepPurple,
                      ),
                    );
                    // 弹窗关闭后反向执行动画,切回菜单图标
                    _animationController.reverse();
                    setState(() => isPlaying = false);
                  } else {
                    // 点击关闭图标时主动关闭弹窗
                    if (mounted) {
                      Navigator.pop(context);
                    }
                    _animationController.reverse();
                    setState(() => isPlaying = false);
                  }
                }),
          ],
        ),
        body: const SizedBox.shrink()
    );
  }
}

补充说明

  • 新增mounted判断,避免页面销毁后执行上下文操作引发异常
  • 补充了点击关闭图标时主动关闭底部弹窗的逻辑,保证交互一致性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 00:36:04