【问题标题】:Flutter PopupMenuButton - how to disable it conditionallyFlutter PopupMenuButton - 如何有条件地禁用它
【发布时间】:2019-04-19 18:47:28
【问题描述】:

我在appTitle 上有一个简单的PopupMenuButton 实现。这里是:

PopupMenuItem<int> _buildMenuItem(int size) {
  return PopupMenuItem<int>(
    value: size,
    child: Text('${size}x$size'),
  );
}

return Scaffold(
  appBar: AppBar(
    title: Text('Some title'),
    actions: <Widget>[
      PopupMenuButton<int>(
        icon: Icon(Icons.refresh),
        onSelected: _canReplay()
            ? (int size) {
                // do something with the size
              }
            : null,
        itemBuilder: (BuildContext context) => <PopupMenuItem<int>>[
              _buildMenuItem(3),
              _buildMenuItem(4),
              _buildMenuItem(5),
            ],
      ),
    ],
  ),
  body: ...
);

已更新 - 我意识到我最初的问题可能不太清楚,所以我在下面重新表述:

我想要实现的是根据应用条件禁用PopupMenuButton。使用上面的代码,我可以启用/禁用onSelected 方法调用,但是,图标外观不会改变。

总而言之 - 我希望整个 PopupMenuButton 及其图标以相同的方式被禁用,IconButton 被禁用,您将 null 传递给它的 onPressed 方法。这样,用户甚至无法按下按钮并调用菜单。

这可以实现吗?

【问题讨论】:

  • 你能把你的_buildMenuItem的代码放上来吗?
  • buildMenuItem 代码 sn-p 添加

标签: flutter


【解决方案1】:

您可以使用PopupMenuItem 小部件的enabled 属性。

  PopupMenuItem<int> _buildMenuItem(int size, bool enabled) {
    return PopupMenuItem<int>(
      value: size,
      child: Text('${size}x$size'),
      enabled: enabled,
    );
  }


      itemBuilder: (BuildContext context) => <PopupMenuItem<int>>[
        _buildMenuItem(3, true),
        _buildMenuItem(4, false),
        _buildMenuItem(5, true),
      ],

更多信息:https://docs.flutter.io/flutter/material/PopupMenuItem/enabled.html

更新

根据您向我们提供的有关您的问题的新信息,无法使用 PopupMenuButton 按钮禁用该按钮,但这是 Flutter,因此您可以创建自己的 Widget。

我创建了一个自定义PopupMenuButton,您可以在其中使用enabled 属性,看看:

https://gist.github.com/diegoveloper/a388dd42a01ffff04cd51ec026381fe3

用法:

    MyOwnPopupMenuButton<int>(
          enabled: _canReplay(),
          icon: Icon(
            Icons.refresh,
            color: _canReplay() ? Colors.black : Colors.black.withOpacity(0.4),
          ),
          onSelected: _canReplay()
              ? (int size) {
                  // do something with the size
                }
              : null,
          itemBuilder: (BuildContext context) => <PopupMenuItem<int>>[
                _buildMenuItem(3),
                _buildMenuItem(4),
                _buildMenuItem(5),
              ],
        )

【讨论】:

  • 我意识到我的问题可能不太清楚,因此我更新了它。无论如何-您上面的建议不起作用,因为我需要禁用整个弹出菜单及其图标。您的建议将禁用特定菜单项,但菜单本身仍然可以打开,这不是理想的结果。
  • 不,它不会起作用 - 这会改变图标 color,但是,图标仍然是 可点击,因此用户可以点击它并打开菜单。
【解决方案2】:

几个小时后,我最终得到了以下解决方案,它符合我的要求,并且它是在没有任何复杂的自定义小部件的情况下实现的。这里是:

return Scaffold(
  appBar: AppBar(
    title: Text(allTranslations.text('Some title')),
    actions: <Widget>[
      _canReplay()
          ? PopupMenuButton<int>(
              icon: Icon(Icons.refresh),
              onSelected: (int size) {
                // do something with size
              },
              itemBuilder: (BuildContext context) => <PopupMenuItem<int>>[
                    _buildMenuItem(3),
                    _buildMenuItem(4),
                    _buildMenuItem(5),
                  ],
            )
          : IconButton(
              icon: Icon(Icons.refresh),
        onPressed: null,
            ),
    ],
  ),
  body: ...
);

【讨论】:

  • 我很欣赏这个答案,但不能完全隐藏一些底部菜单?
  • 完全隐藏在一些底部菜单中是什么意思?预期的行为是什么?
  • 我想隐藏特定菜单而不是为上述情况保留刷新按钮
  • 我明白了,然后将上面代码中的IconButton( icon: Icon(Icons.refresh), onPressed: null, )替换为Container()。这应该可以解决问题。
猜你喜欢
  • 2019-07-30
  • 1970-01-01
  • 2022-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-15
  • 1970-01-01
  • 2019-11-26
相关资源
最近更新 更多