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

Flutter PopupMenuButton选中条目时如何阻止菜单自动关闭

问题根源

PopupMenuItem 内置的点击处理逻辑默认会执行 Navigator.pop(context, value) 关闭弹出菜单,这是点击后菜单自动关闭的核心原因。

可行解决方案

不需要自定义PopupMenuItem类,仅需修改现有代码的3处逻辑即可实现多选不关闭菜单:

  1. 禁用PopupMenuItem的默认点击响应,避免触发自动关闭
  2. 将选中逻辑移到菜单条目内部的ListTile的点击事件中自行处理
  3. 手动修复禁用PopupMenuItem后导致的文字/图标置灰问题

修改后的完整实现代码如下:

class TopicsNotificationMenu extends StatefulWidget {
  List<Topic> topics = [];
  TopicsNotificationMenu(this.topics);

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

class _TopicsNotificationMenuState extends State<TopicsNotificationMenu> {
  _TopicsNotificationMenuState();
  
  _updateTopics(_tp){
    setState(() {
      if(_tp.value == true){
        _tp.value = false;
      }else{
        _tp.value = true;
        _registerTopic(_tp.name);
      }
    });
  }

  // 原有_registerTopic逻辑保留即可,无需修改
  _registerTopic(String name){
    // 你的原有业务逻辑
  }

  @override
  Widget build(BuildContext context) {
    return PopupMenuButton(
      // 删除原有onSelected回调,不再使用PopupMenuItem默认选中逻辑
      itemBuilder: (BuildContext context) {  
        return widget.topics.map((var tp) {
          var _icon = (tp.value == true) ? Icons.check_box : Icons.check_box_outline_blank;
          return PopupMenuItem(
            // 禁用默认点击事件,阻止自动关闭菜单
            enabled: false,
            child: ListTile(
              // 手动设置正常色值,避免禁用PopupMenuItem导致内容置灰
              textColor: Theme.of(context).textTheme.titleMedium?.color,
              iconColor: Theme.of(context).iconTheme.color,
              leading: Icon(_icon),
              title: Text(tp.name),
              // 自行处理点击逻辑,更新状态时菜单不会关闭
              onTap: () => _updateTopics(tp),
            ),
          );
        }).toList();
      }
    );
  }
}
补充说明

如果需要保留条目点击的水波纹效果,可将ListTile包裹在InkWell组件中,交互体验和原生菜单完全一致。如果需要增加关闭菜单的触发逻辑,可额外添加一个底部操作条目,在它的点击事件中手动调用Navigator.pop(context)即可关闭菜单。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 03:21:02