相信在实际开发过程中,确定少不了这样的功能:html
点击 AppBar
右上角的按钮,弹出一个菜单供用户选择。git
幸运的是,Flutter 提供给咱们了一个 Widget,直接就能实现如上的效果。github
仍是老规矩,先看官方的说明: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
oricon
,可是不能同时提供。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,咱们来看一下运行效果:
再来看一下代码:
/// 首先定义了一个枚举
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(),
);
}
复制代码
解释一下逻辑:
AppBar
的「actions」里定义了 PopupMenuButton
Icon(Icons.more_vert)
itemBuilder
需返回一个 List<PopupMenuEntry<T>>
PopupMenuItem<WhyFarther>
onSelected
参数接收点击回调这样总体的逻辑就是定义好了,运行一下:
这样就完成了一个超级简单而且实用的菜单弹出框,
其实它的实现逻辑和 DropdownButton
差很少,都是使用了 PopupRoute
,
有对这方面感兴趣的同窗,能够查看我之前写的文章:Flutter 源码系列:DropdownButton 源码浅析
完整代码已经传至GitHub:github.com/wanglu1209/…