我的弹出菜单中有一个复选框项(PopupMenuItem)列表,它由 popupMenuButton 触发。我希望用户能够选择多个复选框,但是一旦选择了一项,它就会关闭窗口。
有什么办法可以防止这种情况发生吗?我需要它保持打开状态,或者立即强制它再次打开。
(我尝试创建自己的 PopupItem 类来覆盖“handleTap()”,但我需要更新父菜单视图的状态,我无法从另一个类调用它。所以我再次删除了它。)
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);
}
});
}
@override
Widget build(BuildContext context) {
return PopupMenuButton(
onSelected: (value) {
_updateTopics(value);
},
itemBuilder: (BuildContext context) {
return widget.topics.map((var tp) {
var _icon = (tp.value == true) ? Icons.check_box : Icons.check_box_outline_blank;
return PopupMenuItem(
value: tp,
child: ListTile(
leading: Icon(_icon),
title: Text(tp.name),
),
);
}).toList();
});
}
我必须为此创建自己的小部件。总之,我想要在屏幕右上角有一个浮动列表,其中包含复选框项目的列表。当我按下这些项目时,它们会被选中/取消选中,但窗口保持打开状态,直到我单击它为止。我使用了以下小部件树:
An OverlayEntry widget so that I could place it anywhere floating above the app
-> added the SafeArea widget so that my padding would include the notification bar at the top of the phone
-> a Gesture Detector, so that on tapping off it I could close it
-> a column with CrossAxisAlignment.end so that it was placed in the top-right
-> a container widget with some padding
-> a Material for elevation shading and to contain a list
-> The Listview
-> The List Tiles with icon and Text for each item. The icon was either the ticked or unticked graphic, depending on it's value (which is stored as a boolean in an array)
ListTile 的 onTap 它更新了小部件的状态并再次显示它。没有视觉眨眼,它是即时的。
手势检测器的 onTap 它只是删除小部件。
您可以继承
PopupMenuButton
并重写它的
handleTap
方法,如下所示:
class NonDismissingPopupMenuItem<T> extends PopupMenuItem<T> {
const NonDismissingPopupMenuItem(
{super.key,
super.value,
super.onTap,
super.enabled = true,
super.height = kMinInteractiveDimension,
super.padding,
super.textStyle,
super.labelTextStyle,
super.mouseCursor,
super.child});
@override
PopupMenuItemState<T, PopupMenuItem<T>> createState() => _NonDismissingPopupMenuItem<T, PopupMenuItem<T>>();
}
class _NonDismissingPopupMenuItem<T, W extends PopupMenuItem<T>> extends PopupMenuItemState<T, W> {
@override
void handleTap() {
widget.onTap?.call(); // this override prevents popup menu to close
}
}
这不会调用父级的 handleTap
,因此不会关闭 PopupMenu,同时仍然允许您使用点击回调。