选择项目后如何不关闭 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 个问题

  1. 选择项目时弹出窗口被关闭
  2. 单击复选框不会更新复选框状态
  3. 单击文本未更新复选框

所以我就这样解决了所有这些问题,这可能会对你们有所帮助

  1. 在 PopupMenuItem 中设置 enabled = false 并为点击侦听器使用手势侦听器包装子项
  2. 使用StatefulBuilder更新状态
  3. 解决方案 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);
}