Flutter | 超实用简单菜单弹出框 PopupMenuButton

相信在实际开发过程中,确定少不了这样的功能:html

点击 AppBar 右上角的按钮,弹出一个菜单供用户选择。git

幸运的是,Flutter 提供给咱们了一个 Widget,直接就能实现如上的效果。github

PopupMenuButton

仍是老规矩,先看官方的说明:api

Displays a menu when pressed and calls onSelected when the menu is dismissed because an item was selected. The value passed to onSelected is the value of the selected menu item.markdown

One of child or icon may be provided, but not both. If icon is provided, then PopupMenuButton behaves like an IconButton.app

If both are null, then a standard overflow icon is created (depending on the platform).ide

大体意思为:函数

当按下的时候显示一个菜单,选择了一个项目的时候会回调 onSelected,传递的值是所选菜单的值。ui

能够提供 child or icon ,可是不能同时提供。this

若是为空,则提供一个默认的图标,取决于平台。

构造函数

看完了官方说明,再来看构造函数:

const PopupMenuButton({
  Key key,
  @required this.itemBuilder,
  this.initialValue,
  this.onSelected,
  this.onCanceled,
  this.tooltip,
  this.elevation = 8.0,
  this.padding = const EdgeInsets.all(8.0),
  this.child,
  this.icon,
  this.offset = Offset.zero,
  this.enabled = true,
}) : assert(itemBuilder != null),
assert(offset != null),
assert(enabled != null),
assert(!(child != null && icon != null)), // fails if passed both parameters
super(key: key);
复制代码

这里面每个参数应该都很好理解,就不作过多的解释了,

惟一必传的参数就是 itemBuilder,也能够看到后面的断言:

assert(!(child != null && icon != null)) 判断了 child 、icon 是否同时不为空,若是是的话就报错了。

简单 Demo

构造函数理解了,官方也提供了一个 Demo,咱们来看一下运行效果:

再来看一下代码:

/// 首先定义了一个枚举
enum WhyFarther {
  harder,
  smarter,
  selfStarter,
  tradingCharter,
}

/// ------------------------------------

/// build 方法
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text('PopupMenuButtonPage'),
      actions: <Widget>[
        PopupMenuButton<WhyFarther>(
          onSelected: (WhyFarther result) {
            setState(() {
              _selection = result;
            });
          },
          icon: Icon(Icons.more_vert),
          itemBuilder: (BuildContext context) => <PopupMenuEntry<WhyFarther>>[
            const PopupMenuItem<WhyFarther>(
              value: WhyFarther.harder,
              child: Text('Working a lot harder'),
            ),
            const PopupMenuItem<WhyFarther>(
              value: WhyFarther.smarter,
              child: Text('Being a lot smarter'),
            ),
            const PopupMenuItem<WhyFarther>(
              value: WhyFarther.selfStarter,
              child: Text('Being a self-starter'),
            ),
            const PopupMenuItem<WhyFarther>(
              value: WhyFarther.tradingCharter,
              child: Text('Placed in charge of trading charter'),
            ),
          ],
        ),
      ],
    ),
    body: Container(),
  );
}
复制代码

解释一下逻辑:

  1. 首先定义了一个枚举
  2. 而后在 AppBar 的「actions」里定义了 PopupMenuButton
  3. 设置 icon 为 Icon(Icons.more_vert)
  4. itemBuilder 需返回一个 List<PopupMenuEntry<T>>
  5. 这里传入的值就是 PopupMenuItem<WhyFarther>
  6. 而后定义 onSelected 参数接收点击回调

这样总体的逻辑就是定义好了,运行一下:

总结

这样就完成了一个超级简单而且实用的菜单弹出框,

其实它的实现逻辑和 DropdownButton 差很少,都是使用了 PopupRoute

有对这方面感兴趣的同窗,能够查看我之前写的文章:Flutter 源码系列:DropdownButton 源码浅析

完整代码已经传至GitHub:github.com/wanglu1209/…

img
相关文章
相关标签/搜索