选择项目后如何不关闭 PopUpMenuButton?
Posted
技术标签:
【中文标题】选择项目后如何不关闭 PopUpMenuButton?【英文标题】:How not to dismiss a PopUpMenuButton after selecting an item? 【发布时间】:2020-08-12 04:18:05 【问题描述】:我正在使用颤振的 PopUpMenuButton。我想要的是当我选择菜单上的任何项目时,不应关闭弹出窗口,而是让我从弹出窗口中选择多个值。文档说您可以覆盖 handleTap 属性,但我不清楚该怎么做那? 这是记录在案的
///The [handleTap] method can be overridden to adjust exactly what happens when
/// the item is tapped. By default, it uses [Navigator.pop] to return the
/// [PopupMenuItem.value] from the menu route.
void handleTap()
Navigator.pop<T>(context, widget.value);
【问题讨论】:
【参考方案1】:创建一个自定义类,比如PopupItem
,它扩展PopupMenuItem
并覆盖PopupMenuItemState.handleTap
方法。
class PopupItem extends PopupMenuItem
const PopupItem(
required Widget child,
Key? key,
) : super(key: key, child: child);
@override
_PopupItemState createState() => _PopupItemState();
class _PopupItemState extends PopupMenuItemState
@override
void handleTap()
您现在可以像这样使用它:
PopupMenuButton(
itemBuilder: (_)
return [
PopupItem(child: ...),
];
,
)
【讨论】:
如何在有状态小部件中使用它来更新显示?例如,带有复选框列表的菜单。用户单击复选框,值从开/关切换并在屏幕上更新? @James 肯定不是 cmets 可以解释的。 @James 您还可以从从 PopupMenuItemState 扩展的自定义类中覆盖方法 buildChild() 并将 null 传递给 PopupMenuItem 的子字段。【参考方案2】:所以我有一个必须要做的要求
使用带有可检查项目的下拉菜单创建表单域
所以我用 PopupMenuItem 创建了一个弹出菜单,但后来遇到了 3 个问题
-
当一个项目被选中时,弹出窗口被关闭
单击复选框未更新复选框状态
单击文本未更新复选框
所以我像这样解决了所有这些问题,这可能会对你们有所帮助
-
在 PopupMenuItem 中设置 enabled = false 并使用手势侦听器为单击侦听器包装子项
使用 StatefulBuilder 更新状态
解决方案 1 也解决了这个问题
这里是代码->
onTapDown: (details) async
state.didChange(
await showMenu(
context: context,
position: RelativeRect.fromLTRB(
details.globalPosition.dx,
details.globalPosition.dy,
0,
0,
),
items: itemList.keys
.map(
(e) => PopupMenuItem(
enabled: false,
child: StatefulBuilder(
builder: (BuildContext context,
StateSetter setState)
return GestureDetector(
onTap: ()
setState(()
itemList[e] = !itemList[e]!;
);
,
child: Row(
children: [
Expanded(child: Text(e)),
Checkbox(
value: itemList[e],
onChanged: (i)
setState(()
itemList[e] = i!;
);
,
),
],
),
);
,
),
),
)
.toList(),
elevation: 8.0,
).then((value) => null) ??
[],
);
【讨论】:
完美运行。但是我面临一个问题,文本显示为灰色,因为小部件被禁用(我在弹出菜单中显示了蓝色的文本)。有没有办法覆盖弹出菜单项中的禁用行为 @RahulSingh 您是否尝试添加文本样式? 在你指出我这样做并且它有效之后。感谢您的帮助【参考方案3】:您可以像这样使用 CheckedPopupMenuItem .. 如 Official 文档中所述
PopupMenuButton<Commands>(
onSelected: (Commands result)
switch (result)
case Commands.heroAndScholar:
setState(() _heroAndScholar = !_heroAndScholar; );
break;
case Commands.hurricaneCame:
// ...handle hurricane option
break;
// ...other items handled here
,
itemBuilder: (BuildContext context) => <PopupMenuEntry<Commands>>[
CheckedPopupMenuItem<Commands>(
checked: _heroAndScholar,
value: Commands.heroAndScholar,
child: const Text('Hero and scholar'),
),
const PopupMenuDivider(),
const PopupMenuItem<Commands>(
value: Commands.hurricaneCame,
child: ListTile(leading: Icon(null), title: Text('Bring hurricane')),
),
// ...other items listed here
],
)
【讨论】:
这确实有效,但我想添加一个带有动画的自定义单选按钮,我不希望这个 CheckedPopUpMenu 按钮允许我这样做。顺便说一句,感谢您的回答.. 如果我的回答符合您的问题,请投票赞成。我知道你想实现单选按钮而不是 CheckedPopupMenu 按钮,但对于其他用户来说这将是有用的 我刚刚尝试了 CheckedPopUpmenu 按钮,它也不起作用,我不知道为什么,它只是被勾选并且菜单被关闭,我无法选择多个值【参考方案4】:@Omi,
我遇到过类似的情况...想要一个 Popup,但不想在我选择 PopupMenuItem 时将其关闭。
我已经实现了这个:
启用→布尔 是否允许用户选择此项。 [...]
我已将菜单项的 enabled 设置为 false(在我的情况下,它是一张具有我的自定义 UI 的卡片)
【讨论】:
以上是关于选择项目后如何不关闭 PopUpMenuButton?的主要内容,如果未能解决你的问题,请参考以下文章