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

Flutter中移出鼠标时如何关闭PopupMenuButton?

解决Flutter PopupMenuButton鼠标悬停显示/移出关闭问题

你当前通过查找内部GestureDetector触发点击来打开菜单的方式,不仅依赖组件内部结构(版本更新可能失效),还缺少对应的关闭逻辑。以下是更可靠的解决方案:

核心思路

  1. 用GlobalKey<PopupMenuButtonState>直接控制菜单的显示/隐藏,这是官方推荐的稳定方式。
  2. 跟踪鼠标是否在按钮或菜单区域,仅当两者都离开时才关闭菜单,避免用户操作菜单时意外关闭。

修改后的完整代码

// 在State类中定义变量
final GlobalKey<PopupMenuButtonState> _blogMenuKey = GlobalKey();
bool _isButtonHovered = false;
bool _isMenuHovered = false;

// 替换原有的InkWell和PopupMenuButton代码
InkWell(
  onHover: (value) {
    setState(() => _isButtonHovered = value);
    if (value) {
      // 鼠标移入按钮时打开菜单
      _blogMenuKey.currentState?.showButtonMenu();
    } else {
      // 鼠标移出按钮后,若菜单未被hover则关闭
      if (!_isMenuHovered) {
        _blogMenuKey.currentState?.hideMenu();
      }
    }
  },
  onTap: () {},
  child: PopupMenuButton(
    key: _blogMenuKey,
    tooltip: '',
    color: const Color(0xFF262533),
    position: PopupMenuPosition.under,
    child: MouseRegion(
      onEnter: (_) => setState(() => _isButtonHovered = true),
      onExit: (_) => setState(() => _isButtonHovered = false),
      child: Text(
        'Blog',
        style: TextStyle(
          color: _isButtonHovered ? Colors.pink : Colors.white,
          fontSize: 24,
          fontFamily: 'Poppins',
        ),
      ),
    ),
    itemBuilder: (BuildContext context) => <PopupMenuEntry>[
      PopupMenuItem(
        child: MouseRegion(
          onEnter: (_) => setState(() => _isMenuHovered = true),
          onExit: (_) {
            setState(() => _isMenuHovered = false);
            // 鼠标移出菜单后,若按钮未被hover则关闭
            if (!_isButtonHovered) {
              _blogMenuKey.currentState?.hideMenu();
            }
          },
          child: ListTile(
            title: const Text(
              'Archiv',
              style: TextStyle(color: Colors.white),
            ),
            enabled: true,
            hoverColor: Colors.pink,
            onTap: () {
              // 点击选项后关闭菜单
              _blogMenuKey.currentState?.hideMenu();
              // 这里添加选项点击后的业务逻辑
            },
          ),
        ),
      ),
    ],
  ),
),

关键说明

  • 用GlobalKey直接调用showButtonMenu()和hideMenu(),替代原有的内部组件查找方式,避免Flutter版本更新导致代码失效。
  • 通过_isButtonHovered和_isMenuHovered两个状态变量,实现鼠标在按钮/菜单区域的状态跟踪,确保菜单在用户操作时不会意外关闭。
  • 选项点击事件中手动关闭菜单,保证交互逻辑的完整性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 16:05:38