老孟导读:今天介绍下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】:

【Flutter 实战】菜单(Menu)功能的更多相关文章

  1. 【Flutter实战】六大布局组件及半圆菜单案例

    老孟导读:Flutter中布局组件有水平 / 垂直布局组件( Row 和 Column ).叠加布局组件( Stack 和 IndexedStack ).流式布局组件( Wrap )和 自定义布局组件 ...

  2. 菜单Menu(AS开发实战第四章学习笔记)

    4.5 菜单Menu Android的菜单主要分两种,一种是选项菜单OptionMenu,通过按菜单键或点击事件触发,另一种是上下文菜单ContextMenu,通过长按事件触发.页面的布局文件放在re ...

  3. Flutter实战】文本组件及五大案例

    老孟导读:大家好,这是[Flutter实战]系列文章的第二篇,这一篇讲解文本组件,文本组件包括文本展示组件(Text和RichText)和文本输入组件(TextField),基础用法和五个案例助你快速 ...

  4. 【老孟Flutter】Flutter 2的新功能

    老孟导读:昨天期待已久的 Flutter 2.0 终于发布了, Flutter Web和Null安全性趋于稳定,Flutter桌面安全性逐渐转向Beta版! 原文链接:https://medium.c ...

  5. yii2 rbac权限控制之菜单menu详细教程

    作者:白狼 出处:http://www.manks.top/article/yii2_rbac_menu本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则 ...

  6. yii2权限控制rbac之菜单menu最详细教程

    前面我们在博文 yii2搭建完美后台并实现rbac权限控制实例教程中完美实现了yii2的后台搭建和rbac权限控制,如果你还没有实现,请先看上文再回来参考本文,因为本文是在上文的基础上进行完善和补充. ...

  7. 我的第一个python web开发框架(36)——后台菜单管理功能

    对于后台管理系统来说,要做好权限管理离不开菜单项和页面按钮控件功能的管理.由于程序没法智能的知道有什么菜单和控件,哪些人拥有哪些操作权限,所以首先要做的是菜单管理功能,将需要管理的菜单项和各个功能项添 ...

  8. Vue2 实现树形菜单(多级菜单)功能模块

    结构示意图 ├── index.html ├── main.js ├── router │ └── index.js # 路由配置文件 ├── components # 组件目录 │ ├── App. ...

  9. GUI的最终选择 Tkinter(七):菜单Menu组件、Menubutton组件、OptionMenu组件

    Menu组件 今天说的Menu组件就是一些菜单组件,开始点点点... Tkinter提供了一个Menu组件,可以实现顶级菜单,下拉菜单和弹出菜单.由于底层是代码实现和优化的,所以不太建议通过按钮和其他 ...

  10. bootstrap table 父子表实现【无限级】菜单管理功能

    bootstrap table 父子表实现[无限级]菜单管理功能 实现效果 前端代码 <%@ page language="java" import="java.u ...

随机推荐

  1. 设计模式:建造者模式及在jdk中的体现,建造者模式和工厂模式区别

    0.背景 建造模式(Builder模式) 假如有一个需求:盖房子,盖房子过程是一致的:打桩.砌墙.封顶.但是房子是各式各样的,最后盖出来的房子可能是高楼或别墅. 根据直接的思路,不用设计模式思想,我们 ...

  2. 【NOI2015】荷马史诗 - 哈夫曼树

    题目描述 追逐影子的人,自己就是影子 ——荷马 Allison 最近迷上了文学.她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的<荷马史诗>.但是由<奥德赛&g ...

  3. 群晖系统设置链路聚合并配置静态IP的教程【江东网 JDX86.COM】

    1.进入控制面板 > 网络 > 网络接口.请单击创建 > 创建 Bond 2.进入聚合配置向导,选择你想要的模式,这里有几种模式意思分别为: 自适应负载平衡: 此模式优化了 Syno ...

  4. three.js 制作逻辑转体游戏(下)

    上一篇已经对绕非定轴转动有所了解,这篇郭先生继续说一说逻辑转体游戏的制作,这部分我们同样会遇到一些小问题,首先是根据数据渲染陷阱和目标区域,然后是对可以转动的判定,最后是获胜的判定. 1. 根据数据渲 ...

  5. C++ Templates 目录

    第1部分 : 基本概念 第1章 函数模板 1.1 初识函数模板 1.1.1 定义模板 1.1.2 使用模板 1.1.3 二阶段翻译 1.2 模板参数推导 1.3 多模板参数 1.3.1 返回类型的模板 ...

  6. golang container/list 使用

    原文链接:http://cngolib.com/container-list.html(中文),https://golang.org/pkg/container/list/(英文) 示例: packa ...

  7. Vue的Options

    el:挂载点 与$mount有替换关系 new Vue({ el: "#app" }); new Vue({}).$mount('#app') 注:被你选为挂载点的那个元素,如果在 ...

  8. [Redhat虚拟机安装][VirtualBox][NET:Registered protocol family 2]

    错误情况 今晚试着用VirtualBox虚拟机安装RedHat,但是安装过程中一直卡在一个NET:Registered protocol family 2这个地方. 错误截图 情况如下图所示: 解决方 ...

  9. 神舟zx6-ct5da装黑苹果Macos 10.15.6记录

    可能是一时脑子抽风,突然就想体验一把mac系统.以前就了解过,给非苹果电脑装macos叫黑苹果,emmmmm.好吧,给我的神船也整一个. 看了很多个视频,整理一下装黑苹果过程.本人电脑系统是win10 ...

  10. [CSP-S2019]括号树 题解

    CSP-S2 2019 D1T2 刚开考的时候先大概浏览了一遍题目,闻到一股浓浓的stack气息 调了差不多1h才调完,加上T1用了1.5h+ 然而T3还是没写出来,滚粗 思路分析 很容易想到的常规操 ...