【Flutter 实战】菜单(Menu)功能

AlgoRoverPro
• 阅读 1644
老孟导读:今天介绍下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('化学'),
      ),
    ];
  },
)

效果如下:

【Flutter 实战】菜单(Menu)功能

设置其初始值:

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

设置初始值后,打开菜单后,设置的值将会高亮,效果如下:

【Flutter 实战】菜单(Menu)功能

获取用户选择了某一项的值,或者用户未选中,代码如下:

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

tooltip是长按时弹出的提示,用法如下:

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

效果如下:

【Flutter 实战】菜单(Menu)功能

设置其阴影值、内边距和弹出菜单的背景颜色:

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

默认情况下,PopupMenuButton显示3个小圆点,我们也可以对齐进行设置,设置文字如下:

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

child组件将会被InkWell包裹,点击弹出菜单,效果如下:

【Flutter 实战】菜单(Menu)功能

也可以设置其他图标:

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

效果如下:

【Flutter 实战】菜单(Menu)功能

设置弹出菜单边框:

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

效果如下:

【Flutter 实战】菜单(Menu)功能

menu有一个非常重要的参数Offset,这个参数是控制菜单弹出的位置,通常情况下,菜单在当前按钮下面展示:

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

【Flutter 实战】菜单(Menu)功能

PopupMenuButton的每一项都需要是PopupMenuEntry类型,PopupMenuEntry为抽象类,其子类有PopupMenuItem、PopupMenuDivider、CheckedPopupMenuItem。

PopupMenuItem

构造函数为

【Flutter 实战】菜单(Menu)功能

参数说明:

  • 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('英语'),
      ),
    ];
  },
)

【Flutter 实战】菜单(Menu)功能

PopupMenuDivider

PopupMenuDivider是菜单分割线,用法如下:

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

【Flutter 实战】菜单(Menu)功能

PopupMenuDivider默认高度为16,注意这个高度并不是分割线的高度,而是分割线控件的高度,设置为50代码:

PopupMenuDivider(height: 50,),

【Flutter 实战】菜单(Menu)功能

CheckedPopupMenuItem

CheckedPopupMenuItem是前面带是否选中的控件,本质就是一个ListTile,用法如下:

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

【Flutter 实战】菜单(Menu)功能

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参数表示弹出的位置,效果如下:

【Flutter 实战】菜单(Menu)功能

属性和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】:

【Flutter 实战】菜单(Menu)功能【Flutter 实战】菜单(Menu)功能
点赞
收藏
评论区
推荐文章
风花雪月 风花雪月
4年前
tkinter中关闭函数的相关使用
tk中隐藏控件时,得出的结论!commandlambda:win.packforget()多窗口时,此命令只能生效一次commandwin.packforget()运行时,无显示commandwin.packforget多窗口时,此命令可以多次点击生效求教,界面只显示tk菜单当中的一个选项的窗口,如果有子窗口,就无法点击菜单选项?有知道的老铁,麻烦给个链接?!!先谢谢了!
Jack Jack
4年前
仿Windows下记事本小程序
在Windows操作系统中,记事本是一个小的应用程序,采用一个简单的文本编辑器进行文字信息的记录和存储。请仿照Windows的记事本,开发一个属于自己的记事本(Notepad)功能记事本的应该具备的功能,基本要求如下:(1)菜单栏中包含文件、编辑、查看和帮助菜单,具体如下图所示。(2)文件菜单中具有新建、打开、保存、另存为、打印和退出功能,具体如
Stella981 Stella981
3年前
Flutter vs React Native vs Native:深度性能比较
!(https://oscimg.oschina.net/oscnet/up5410e759aa8ea7d5747ab3d9dcc200d3ffe.png)老孟导读:这是老孟翻译的付费文章,文章所有权归原作者所有。欢迎加入老孟Flutter交流群,每周翻译23篇付费文章,精彩不容错过。原文地址:https:/
Stella981 Stella981
3年前
Flutter接入现有iOS工程(混编)、开发调试、打包发布精简教程
本教程是在xcode11.1、cocospod1.7.5、flutter1.10.15pre.115下完成的。    1.安装flutter    按照官网的教程,一步一步来,没什么好说的。https://flutterchina.club/setupmacos/(https://ww
Stella981 Stella981
3年前
Flutter中如何使用WillPopScope
!(https://oscimg.oschina.net/oscnet/up39de92df7002d3e246160ac64f08f7e582b.png)老孟导读:在Flutter中如何实现点击2次Back按钮退出App,如何实现App中多个Route(路由),如何实现Back按钮只退出指定页面,此篇文章将告诉你。WillPopScope
Stella981 Stella981
3年前
PHP Laravel5实现的RBAC权限管理操作示例
根据不同的权限,在菜单栏显示不同的功能,只对菜单进行了限制,若对路由也进行限制,可以根据菜单的例子,请自行完善,开发。下面请认真学习一下laravel的RBAC设计1、建表(用户表、角色表、权限表、用户角色表、角色权限表)1CREATETABLEIFNOTEXISTSmr_role2(3id
Stella981 Stella981
3年前
OFBiz 快速入门——续二
OFBiz快速入门——续二2011年03月17日星期四00:03OFBiz 快速入门2.5 创建一个文件,取名为(controller.xml),被OFBiz webapp控制器使用的。在没有额外增加功能时,这个文件内容非常的小与简单,如下:<?xml version"1.0" encoding"UTF8"?<siteco
Stella981 Stella981
3年前
Android studio中创建一个Menu方法
1.先在res目录下新建一个menu文件夹(右键res目录NewDirectory)输入文件夹名为menu,点击OK2.在新建的menu目录下创建一个名为main的菜单文件(右键menu文件夹NewMenuresourcefile)输入文件名为main点击OK里面内容为:<itemandroid:
Wesley13 Wesley13
3年前
DOM元素的自动隐藏
在一些有悬浮元素的场景中,比如点击一个按钮弹出菜单后,点击菜单以外的地方,菜单应该被隐藏起来。隐藏的方式最好是自动隐藏,或至少是组件内的自动隐藏。蒙层比如,一个模态框组件(闭包实现)点击蒙层时,响应蒙层的点击事件,可以在事件处理函数中隐藏整个组件。在Vue和React等框架的组件中,这一点非常容易实现。<divclass"com
Stella981 Stella981
3年前
SpringBoot 读取properties配置文件 @Value使用 中文乱码问题
一,idea中配置文件中文乱码问题使用idea开发,读取properites配置文件配置:app菜单没有限制,所有人都可访问的菜单menu.unlimited订单审批,现场尽调,合作贷审批客户经理菜单menu.customerManager建档,订单申请,提款申请Config