老孟導讀:今天介紹下Flutter中的菜單功能。git
使用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。
構造函數爲
參數說明:
onSelected
返回。用法以下:
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是菜單分割線,用法以下:
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是前面帶是否選中的控件,本質就是一個ListTile,用法以下:
PopupMenuButton<String>( onSelected: (value) { print('$value'); }, itemBuilder: (context) { return <PopupMenuEntry<String>>[ CheckedPopupMenuItem( value: '語文', checked: true, child: Text('語文'), ), CheckedPopupMenuItem( value: '數學', child: Text('數學'), ), ]; }, )
若是你看下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】: