选择项目后如何不关闭 PopUpMenuButton?
How not to dismiss a PopUpMenuButton after selecting an item?
我正在使用 flutter PopUpMenuButton。我想要的只是当我 select 菜单上的任何项目时,弹出窗口不应该被关闭,而是让我 select 来自 popup.The 文档的多个值说你可以覆盖 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);
}
创建自定义 class,比如 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: ...),
];
},
)
您可以像这样使用 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
],
)
@Omi,
我遇到过类似的情况...想要一个 Popup 但不希望它在我 select PopupMenuItem 时被关闭。
我已经实现了这个:
启用→布尔
是否允许用户 select 此项目。 [...]
我已将菜单项的 enabled 设置为 false(在我的例子中,这是一张具有我的自定义 UI)
所以我有一个必须的要求
create a form field with a drop-down menu with checkable items
所以我用 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) ??
[],
);
}
您必须修改包弹出菜单按钮。每当在菜单中选择某些内容时,菜单就会弹出。所以你必须在这个小部件的主文件中注释掉 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);
}
我正在使用 flutter PopUpMenuButton。我想要的只是当我 select 菜单上的任何项目时,弹出窗口不应该被关闭,而是让我 select 来自 popup.The 文档的多个值说你可以覆盖 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);
}
创建自定义 class,比如 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: ...),
];
},
)
您可以像这样使用 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
],
)
@Omi,
我遇到过类似的情况...想要一个 Popup 但不希望它在我 select PopupMenuItem 时被关闭。
我已经实现了这个:
启用→布尔 是否允许用户 select 此项目。 [...]
我已将菜单项的 enabled 设置为 false(在我的例子中,这是一张具有我的自定义 UI)
所以我有一个必须的要求
create a form field with a drop-down menu with checkable items
所以我用 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) ??
[],
);
}
您必须修改包弹出菜单按钮。每当在菜单中选择某些内容时,菜单就会弹出。所以你必须在这个小部件的主文件中注释掉 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);
}