【问题标题】:How not to dismiss a PopUpMenuButton after selecting an item?选择项目后如何不关闭 PopUpMenuButton?
【发布时间】: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);
  }

【问题讨论】:

    标签: flutter overriding flutter-layout dart-pub popupmenubutton


    【解决方案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 个问题

    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) ??
                      [],
                );
              }
    

    【讨论】:

    • 完美运行。但是我面临一个问题,文本显示为灰色,因为小部件被禁用(我在弹出菜单中显示了蓝色的文本)。有没有办法覆盖弹出菜单项中的禁用行为
    • @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 的卡片)

    【讨论】:

      猜你喜欢
      • 2020-03-26
      • 2021-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-24
      • 1970-01-01
      • 2014-12-11
      相关资源
      最近更新 更多