Flutter PopupMenuButton选中条目时如何阻止菜单自动关闭
问题根源
PopupMenuItem 内置的点击处理逻辑默认会执行 Navigator.pop(context, value) 关闭弹出菜单,这是点击后菜单自动关闭的核心原因。
可行解决方案
不需要自定义PopupMenuItem类,仅需修改现有代码的3处逻辑即可实现多选不关闭菜单:
- 禁用PopupMenuItem的默认点击响应,避免触发自动关闭
- 将选中逻辑移到菜单条目内部的ListTile的点击事件中自行处理
- 手动修复禁用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
相关产品推荐
相关产品推荐

