我正在使用flutter 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);
}
创建一个自定义类,比如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: ...),
];
},
)
所以我有一个必须的要求
创建一个带有可检查项目的下拉菜单的表单字段
所以我用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) ??
[],
);
}
您可以像这样使用CheckedPopupMenuItem。。如官方文件中所述
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
],
)
@Omi,
我也遇到过类似的情况。。。想要一个Popup,但不希望在选择PopupMenuItem时将其取消。
我已经实现了这个:
已启用→bool是否允许用户选择此项目。[…]
我已将菜单项的enabled设置为false(在我的情况下,这是一张具有自定义UI的卡(
您必须修改软件包弹出菜单按钮。每当在菜单中选择某个内容时,菜单就会弹出。因此,您只需注释掉该小部件主文件中的Navigator.pop((即可。评论主文件中的Navigator.pop<T>(context, widget.value);
。
/// The handler for when the user selects the menu item.
///
/// Used by the [InkWell] inserted by the [build] method.
///
/// By default, uses [Navigator.pop] to return the [PopupMenuItem.value] from
/// the menu route.
@protected
void handleTap() {
widget.onTap?.call();
// Navigator.pop<T>(context, widget.value);
}