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
相關文章
相關標籤/搜索