3

我正在使用颤振的 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);
  }
4

5 回答 5

5

创建一个自定义类,比如说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: ...),
    ];
  },
)
于 2020-04-28T11:22:54.027 回答
3

所以我有一个我必须做的要求

使用带有可检查项目的下拉菜单创建表单域

所以我用 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) ??
                  [],
            );
          }
于 2021-07-30T07:44:12.540 回答
1

@Omi,

我遇到过类似的情况......想要一个弹出窗口,但不希望在我选择 PopupMenuItem 时将其关闭。

我已经实现了这个:

enabled → bool 是否允许用户选择此项。[...]

我已将菜单项的enabled设置为false(在我的情况下,它是一张具有我的自定义 UI 的卡片)

于 2021-06-11T04:10:54.613 回答
1

您必须修改软件包弹出菜单按钮。每当在菜单中选择某些内容时,菜单就会弹出。因此,您只需在此小部件的主文件中注释掉 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);
}
于 2022-02-10T05:35:46.510 回答
1

您可以像这样使用 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
      ],
    )
于 2020-04-28T12:08:44.803 回答