【Flutter 實戰】菜單(Menu)功能

老孟導讀:今天介紹下Flutter中的菜單功能git

PopupMenuButton

使用PopupMenuButton,點擊時彈出菜單,用法以下:微信

PopupMenuButton<String>(
  itemBuilder: (context) {
    return <PopupMenuEntry<String>>[
      PopupMenuItem<String>(
        value: '語文',
        child: Text('語文'),
      ),
      PopupMenuItem<String>(
        value: '數學',
        child: Text('數學'),
      ),
      PopupMenuItem<String>(
        value: '英語',
        child: Text('英語'),
      ),
      PopupMenuItem<String>(
        value: '生物',
        child: Text('生物'),
      ),
      PopupMenuItem<String>(
        value: '化學',
        child: Text('化學'),
      ),
    ];
  },
)

效果以下:ide

設置其初始值:函數

PopupMenuButton<String>(
  initialValue: '語文',
  ...
)

設置初始值後,打開菜單後,設置的值將會高亮,效果以下:ui

獲取用戶選擇了某一項的值,或者用戶未選中,代碼以下:3d

PopupMenuButton<String>(
  onSelected: (value){
    print('$value');
  },
  onCanceled: (){
    print('onCanceled');
  },
  ...
)

tooltip是長按時彈出的提示,用法以下:code

PopupMenuButton<String>(
  tooltip: 'PopupMenuButton',
  ...
)

效果以下:blog

設置其陰影值、內邊距和彈出菜單的背景顏色:ip

PopupMenuButton<String>(
  elevation: 5,
  padding: EdgeInsets.all(5),
  color: Colors.red,
  ...
)

默認狀況下,PopupMenuButton顯示3個小圓點,咱們也能夠對齊進行設置,設置文字以下:ci

PopupMenuButton<String>(
  child: Text('學科'),
  ...
)

child組件將會被InkWell包裹,點擊彈出菜單,效果以下:

也能夠設置其餘圖標:

PopupMenuButton<String>(
	icon: Icon(Icons.add),
	...
)

效果以下:

設置彈出菜單邊框:

PopupMenuButton<String>(
  shape: RoundedRectangleBorder(
    side: BorderSide(
      color: Colors.red
    ),
    borderRadius: BorderRadius.circular(10)
  ),
	...
)

效果以下:

menu有一個很是重要的參數Offset,這個參數是控制菜單彈出的位置,一般狀況下,菜單在當前按鈕下面展現:

PopupMenuButton<String>(
  offset: Offset(0,100),
  itemBuilder: (context) {
    return <PopupMenuEntry<String>>[
      PopupMenuItem<String>(
        value: '語文',
        child: Text('語文'),
      ),
      PopupMenuItem<String>(
        value: '數學',
        child: Text('數學'),
      ),
    ];
  },
)

PopupMenuButton的每一項都須要是PopupMenuEntry類型,PopupMenuEntry爲抽象類,其子類有PopupMenuItem、PopupMenuDivider、CheckedPopupMenuItem。

PopupMenuItem

構造函數爲

image-20200522160319731

參數說明:

  • value:當此項選中後,此值將會經過onSelected返回。
  • enabled:此項是否可用。
  • height:此項的高度
  • textStyle:文本樣式
  • child:子控件。

用法以下:

PopupMenuButton<String>(
  onSelected: (value) {
    print('$value');
  },
  itemBuilder: (context) {
    return <PopupMenuEntry<String>>[
      PopupMenuItem<String>(
        value: '語文',
        enabled: false,
        child: Text('語文'),
      ),
      PopupMenuItem<String>(
        value: '數學',
        textStyle: TextStyle(color: Colors.red),
        child: Text('數學'),
      ),
      PopupMenuItem<String>(
        value: '英語',
        height: 100,
        child: Text('英語'),
      ),
    ];
  },
)

PopupMenuDivider

PopupMenuDivider是菜單分割線,用法以下:

PopupMenuButton<String>(
  onSelected: (value) {
    print('$value');
  },
  itemBuilder: (context) {
    return <PopupMenuEntry<String>>[
      PopupMenuItem<String>(
        value: '語文',
        child: Text('語文'),
      ),
      PopupMenuDivider(),
      PopupMenuItem<String>(
        value: '數學',
        child: Text('數學'),
      ),
    ];
  },
)

PopupMenuDivider默認高度爲16,注意這個高度並非分割線的高度,而是分割線控件的高度,設置爲50代碼:

PopupMenuDivider(height: 50,),

CheckedPopupMenuItem

CheckedPopupMenuItem是前面帶是否選中的控件,本質就是一個ListTile,用法以下:

PopupMenuButton<String>(
  onSelected: (value) {
    print('$value');
  },
  itemBuilder: (context) {
    return <PopupMenuEntry<String>>[
      CheckedPopupMenuItem(
        value: '語文',
        checked: true,
        child: Text('語文'),
      ),
      CheckedPopupMenuItem(
        value: '數學',
        child: Text('數學'),
      ),
    ];
  },
)

showMenu

若是你看下PopupMenuButton的源碼會發現,PopupMenuButton也是使用showMenu實現的,用法以下:

showMenu(
    context: context,
    position: RelativeRect.fill,
    items: <PopupMenuEntry>[
      PopupMenuItem(child: Text('語文')),
      PopupMenuDivider(),
      CheckedPopupMenuItem(
        child: Text('數學'),
        checked: true,
      ),
      PopupMenuDivider(),
      PopupMenuItem(child: Text('英語')),
    ]);

position參數表示彈出的位置,效果以下:

屬性和PopupMenuButton基本同樣,但使用showMenu須要咱們指定位置,因此通常狀況下,咱們不會直接使用showMenu,而是使用PopupMenuButton,免去了計算位置的過程。

看下PopupMenuButton是如何計算的,有助於幫助咱們理解:

final PopupMenuThemeData popupMenuTheme = PopupMenuTheme.of(context);
    final RenderBox button = context.findRenderObject();
    final RenderBox overlay = Overlay.of(context).context.findRenderObject();
    final RelativeRect position = RelativeRect.fromRect(
      Rect.fromPoints(
        button.localToGlobal(widget.offset, ancestor: overlay),
        button.localToGlobal(button.size.bottomRight(Offset.zero), ancestor: overlay),
      ),
      Offset.zero & overlay.size,
    );
    final List<PopupMenuEntry<T>> items = widget.itemBuilder(context);

交流

老孟Flutter博客地址(330個控件用法):http://laomengit.com

歡迎加入Flutter交流羣(微信:laomengit)、關注公衆號【老孟Flutter】:

相關文章
相關標籤/搜索