老孟導讀:今天介紹下Flutter中的菜單功能。
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('化學'),
),
];
},
)
效果如下:
設置其初始值:
PopupMenuButton<String>(
initialValue: '語文',
...
)
設置初始值后,打開菜單后,設置的值將會高亮,效果如下:
獲取用戶選擇了某一項的值,或者用戶未選中,代碼如下:
PopupMenuButton<String>(
onSelected: (value){
print('$value');
},
onCanceled: (){
print('onCanceled');
},
...
)
tooltip
是長按時彈出的提示,用法如下:
PopupMenuButton<String>(
tooltip: 'PopupMenuButton',
...
)
效果如下:
設置其陰影值、內邊距和彈出菜單的背景顏色:
PopupMenuButton<String>(
elevation: 5,
padding: EdgeInsets.all(5),
color: Colors.red,
...
)
默認情況下,PopupMenuButton顯示3個小圓點,我們也可以對齊進行設置,設置文字如下:
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
構造函數為
參數說明:
- 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】:
![]() |
![]() |