Flutter 超實(shí)用簡單菜單彈出框 PopupMenuButton功能
相信在實(shí)際開發(fā)過程當(dāng)中,肯定少不了這樣的功能:

點(diǎn)擊 AppBar 右上角的按鈕,彈出一個菜單供用戶選擇。
幸運(yùn)的是,F(xiàn)lutter 提供給我們了一個 Widget,直接就能實(shí)現(xiàn)如上的效果。
PopupMenuButton
還是老規(guī)矩,先看官方的說明:
Displays a menu when pressed and calls onSelected [1] when the menu is dismissed because an item was selected. The value passed to onSelected [2] is the value of the selected menu item.
One of child [3] or icon [4] may be provided, but not both. If icon [5] is provided, then PopupMenuButton [6] behaves like an IconButton [7] .
If both are null, then a standard overflow icon is created (depending on the platform).
大致意思為:
當(dāng)按下的時候顯示一個菜單,選擇了一個項目的時候會回調(diào) onSelected ,傳遞的值是所選菜單的值。
可以提供 child or icon ,但是不能同時提供。
如果為空,則提供一個默認(rèn)的圖標(biāo),取決于平臺。
構(gòu)造函數(shù)
看完了官方說明,再來看構(gòu)造函數(shù):
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);
這里面每一個參數(shù)應(yīng)該都很好理解,就不做過多的解釋了,
唯一必傳的參數(shù)就是 itemBuilder ,也可以看到后面的斷言:
assert(!(child != null && icon != null)) 判斷了 child 、icon 是否同時不為空,如果是的話就報錯了。
簡單 Demo
構(gòu)造函數(shù)理解了,官方也提供了一個 Demo,我們來看一下運(yùn)行效果:

再來看一下代碼:
/// 首先定義了一個枚舉
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. 設(shè)置 icon 為 Icon(Icons.more_vert)
4. itemBuilder 需返回一個 List<PopupMenuEntry<T>>
5. 這里傳入的值就是 PopupMenuItem<WhyFarther>
6. 然后定義 onSelected 參數(shù)接收點(diǎn)擊回調(diào)
這樣整體的邏輯就是定義好了,運(yùn)行一下:

總結(jié)
這樣就完成了一個超級簡單并且實(shí)用的菜單彈出框,
其實(shí)它的實(shí)現(xiàn)邏輯和 DropdownButton 差不多,都是使用了 PopupRoute ,
有對這方面感興趣的同學(xué),可以查看我以前寫的文章: Flutter 源碼系列:DropdownButton 源碼淺析
完整代碼已經(jīng)傳至GitHub:https://github.com/wanglu1209/WFlutterDemo
References
[1] onSelected: https://api.flutter.dev/flutter/material/PopupMenuButton/onSelected.html
[2] onSelected: https://api.flutter.dev/flutter/material/PopupMenuButton/onSelected.html
[3] child: https://api.flutter.dev/flutter/material/PopupMenuButton/child.html
[4] icon: https://api.flutter.dev/flutter/material/PopupMenuButton/icon.html
[5] icon: https://api.flutter.dev/flutter/material/PopupMenuButton/icon.html
[6] PopupMenuButton: https://api.flutter.dev/flutter/material/PopupMenuButton-class.html
[7] IconButton: https://api.flutter.dev/flutter/material/IconButton-class.html
總結(jié)
以上所述是小編給大家介紹的Flutter 超實(shí)用簡單菜單彈出框 PopupMenuButton功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
如果你覺得本文對你有幫助,歡迎轉(zhuǎn)載,煩請注明出處,謝謝!

