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

399d4b3889eb6eb900ec920207e405fa.png

点击 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,咱们来看一下运行效果:

399d4b3889eb6eb900ec920207e405fa.png

再来看一下代码:

/// 首先定义了一个枚举

enum WhyFarther {

harder,

smarter,

selfStarter,

tradingCharter,

}

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

/// build 方法

Widget build(BuildContext context) {

return Scaffold(

appBar: AppBar(

title: Text('PopupMenuButtonPage'),

actions: [

PopupMenuButton(

onSelected: (WhyFarther result) {

setState(() {

_selection = result;

});

},

icon: Icon(Icons.more_vert),

itemBuilder: (BuildContext context) => >[

const PopupMenuItem(

value: WhyFarther.harder,

child: Text('Working a lot harder'),

),

const PopupMenuItem(

value: WhyFarther.smarter,

child: Text('Being a lot smarter'),

),

const PopupMenuItem(

value: WhyFarther.selfStarter,

child: Text('Being a self-starter'),

),

const PopupMenuItem(

value: WhyFarther.tradingCharter,

child: Text('Placed in charge of trading charter'),

),

],

),

],

),

body: Container(),

);

}

复制代码

解释一下逻辑:

首先定义了一个枚举

而后在 AppBar 的「actions」里定义了 PopupMenuButton

设置 icon 为 Icon(Icons.more_vert)

itemBuilder 需返回一个 List>

这里传入的值就是 PopupMenuItem

而后定义 onSelected 参数接收点击回调

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

56adca6da9fb38a93d929a76ec1b13c2.gif

总结

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

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

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐