老孟导读:今天介绍下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】:
![]() |
![]() |