老孟导读:今天介绍下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. 关于 JavaScript 字符串的一个小知识

    说起字符串,我们再熟悉不过了.接触编程的第一个经典任务就是输出字符串:Hello, world.但是你知道 JavaScript 字符串在计算机里是怎么表示的吗? 最简单直观但不太准确的的理解就是,字 ...

  2. 前端进阶必读:《JavaScript核心技术开发解密》核心提炼二

    前言 最近读勒基本关于前端的数据<JavaScript核心技术开发解密>,<webpack从入门到进阶>...这几本书帮助到我更好的理解JS.webpack在前端技术领域中的作 ...

  3. java多线程:线程同步synchronized(不同步的问题、队列与锁),死锁的产生和解决

    0.不同步的问题 并发的线程不安全问题: 多个线程同时操作同一个对象,如果控制不好,就会产生问题,叫做线程不安全. 我们来看三个比较经典的案例来说明线程不安全的问题. 0.1 订票问题 例如前面说过的 ...

  4. Vue源码解析,keep-alive是如何实现缓存的?

    前言 在性能优化上,最常见的手段就是缓存.对需要经常访问的资源进行缓存,减少请求或者是初始化的过程,从而降低时间或内存的消耗.Vue 为我们提供了缓存组件 keep-alive,它可用于路由级别或组件 ...

  5. 转圈游戏C++

    转圈游戏 问题描述 n 个小伙伴(编号从 0 到 n-1)围坐一圈玩游戏.按照顺时针方向给 n 个位置编号,从0 到 n-1.最初,第 0 号小伙伴在第 0 号位置,第 1 号小伙伴在第 1 号位置, ...

  6. VUE 中引入百度地图(vue-Baidu-Map)

    1.安装 $ npm install vue-baidu-map --save 2.全局注册,在main.js中引入以下代码 import BaiduMap from 'vue-baidu-map' ...

  7. SparkStreaming简单例子(oldAPI)

    SparkStreaming简单例子 ◆ 构建第一个Streaming程序: (wordCount) ◆ Spark Streaming 程序最好以使用Maven或者sbt编译出来的独立应用的形式运行 ...

  8. golang ctrie demo

    下载ctrie: go get -t github.com/Workiva/go-datastructures/trie/ctrie 测试demo1: package main import ( &q ...

  9. 浅谈Docker(一)

    注:由于别人写的太好了就转来基础介绍! 转自:http://www.infoq.com/cn/articles/docker-core-technology-preview Docker是PaaS供应 ...

  10. 利用python爬取贝壳网租房信息

    最近准备换房子,在网站上寻找各种房源信息,看得眼花缭乱,于是想着能否将基本信息汇总起来便于查找,便用python将基本信息爬下来放到excel,这样一来就容易搜索了. 1. 利用lxml中的xpath ...