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

點(diǎn)擊 AppBar 右上角的按鈕,彈出一個(gè)菜單供用戶選擇。
幸運(yùn)的是,F(xiàn)lutter 提供給我們了一個(gè) 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)按下的時(shí)候顯示一個(gè)菜單,選擇了一個(gè)項(xiàng)目的時(shí)候會(huì)回調(diào) onSelected ,傳遞的值是所選菜單的值。
可以提供 child or icon ,但是不能同時(shí)提供。
如果為空,則提供一個(gè)默認(rèn)的圖標(biāo),取決于平臺(tái)。
構(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);
這里面每一個(gè)參數(shù)應(yīng)該都很好理解,就不做過多的解釋了,
唯一必傳的參數(shù)就是 itemBuilder ,也可以看到后面的斷言:
assert(!(child != null && icon != null)) 判斷了 child 、icon 是否同時(shí)不為空,如果是的話就報(bào)錯(cuò)了。
簡單 Demo
構(gòu)造函數(shù)理解了,官方也提供了一個(gè) Demo,我們來看一下運(yùn)行效果:

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

總結(jié)
這樣就完成了一個(gè)超級(jí)簡單并且實(shí)用的菜單彈出框,
其實(shí)它的實(shí)現(xiàn)邏輯和 DropdownButton 差不多,都是使用了 PopupRoute ,
有對(duì)這方面感興趣的同學(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功能,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
相關(guān)文章
提交表單時(shí)執(zhí)行func方法實(shí)現(xiàn)代碼
客戶端的js驗(yàn)證想必大家早已熟悉,今天本文帶著大家再回憶一下,主要是在提交表單之前執(zhí)行func方法,感興趣的你可以參考下哈,希望可以幫助到你2013-03-03
用ES6的class模仿Vue寫一個(gè)雙向綁定的示例代碼
本篇文章主要介紹了用ES6的class模仿Vue寫一個(gè)雙向綁定的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-04-04
移動(dòng)端利用H5實(shí)現(xiàn)壓縮圖片上傳功能
這篇文章主要為大家詳細(xì)介紹了移動(dòng)端利用H5實(shí)現(xiàn)壓縮圖片上傳功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03
簡單實(shí)現(xiàn)jquery焦點(diǎn)圖
這篇文章主要為大家詳細(xì)介紹了如何簡單實(shí)現(xiàn)jquery焦點(diǎn)圖效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12
JavaScript評(píng)論點(diǎn)贊功能的實(shí)現(xiàn)方法
通過分析評(píng)論功能的邏輯關(guān)系,學(xué)會(huì)如何使用JavaScript實(shí)現(xiàn)評(píng)論、回復(fù)、點(diǎn)贊等各種功能。這篇文章主要介紹了JavaScript評(píng)論點(diǎn)贊功能的實(shí)現(xiàn)方法,需要的朋友可以參考下2017-03-03
JS實(shí)現(xiàn)商城秒殺倒計(jì)時(shí)功能(動(dòng)態(tài)設(shè)置秒殺時(shí)間)
這篇文章主要介紹了JS實(shí)現(xiàn)商城秒殺倒計(jì)時(shí)功能(動(dòng)態(tài)設(shè)置秒殺時(shí)間),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12
Vue.js實(shí)現(xiàn)頁面后退時(shí)還原滾動(dòng)位置的操作方法
Vuet看起來也不是很復(fù)雜,只需要定義好模塊狀態(tài),然后在組件中設(shè)置對(duì)應(yīng)的規(guī)則來更新模塊的狀態(tài)即可,這篇文章主要介紹了Vue.js實(shí)現(xiàn)頁面后退時(shí)還原滾動(dòng)位置的實(shí)現(xiàn)方法,需要的朋友可以參考下2022-07-07

