Flutter 22: 图解 PopupMenu 那些事儿

      小菜需要处理标题栏弹出对话框 PopupMenu 样式,Flutter 当然提供了一些处理方式,类似 PopupMenuEntry 等,小菜仅就最基础的使用方式进行初步的学习和整理。

PopupMenuItem 基本样式

      PopupMenuItem 为单个 item 的弹出样式,默认为 48px 高,可根据需求自行定义。item 中可以自定义需要的样式,包括文字图片等一系列样式。

@override
Widget build(BuildContext context) {
  return new Scaffold(
      appBar: AppBar(
        title: Text('PopMenuDemo'),
        actions: <Widget>[_NomalPopMenu()],
      ),
      body: Center(child: new Text(_bodyStr)));
}

Widget _NomalPopMenu() {
  return new PopupMenuButton<String>(
      itemBuilder: (BuildContext context) => <PopupMenuItem<String>>[
            new PopupMenuItem<String>(
                value: 'value01', child: new Text('Item One')),
            new PopupMenuItem<String>(
                value: 'value02', child: new Text('Item Two')),
            new PopupMenuItem<String>(
                value: 'value03', child: new Text('Item Three')),
            new PopupMenuItem<String>(
                value: 'value04', child: new Text('I am Item Four'))
          ],
      onSelected: (String value) {
        setState(() { _bodyStr = value; });
      });
}

      Tips: 若需要处理带图标的样式时,官网提供的 Demo 是借助的 ListTile 来处理的,但是小菜测试发现图标与文字距离偏大,原因在于 ListTile 默认左侧图标 leading 距离不可直接调整,建议用 Row 或其他方式调整。

// ListTile 样式
new PopupMenuItem<String>(
    value: 'value01',
    child: ListTile( leading: Icon(Icons.looks_one), title: Text('Item One'))),
// 普通自定义样式
new PopupMenuItem<String>(
    value: 'value01',
    child: Row(children: <Widget>[
      Padding( padding: EdgeInsets.fromLTRB(0.0, 0.0, 8.0, 0.0),
          child: Icon(Icons.looks_one)),
      Text('Item One')
    ])),

CheckedPopupMenuItem 选中样式

      CheckedPopupMenuItem 是一个带有复选标记的弹出菜单项。默认高度同样是 48px,水平布局使用 ListTile 复选标记是 Icons.done 图标,显示在 leading 位置;同时只有在状态为选中时才会显示图标。

Widget _CheckPopMenu() {
  return new PopupMenuButton<String>(
      itemBuilder: (BuildContext context) => <PopupMenuItem<String>>[
            new CheckedPopupMenuItem<String>(
                checked: false, value: 'value01', child: new Text('Item One')),
            new CheckedPopupMenuItem<String>(
                checked: true, value: 'value02', child: new Text('Item Two')),
            new CheckedPopupMenuItem<String>(
                checked: false, value: 'value03', child: new Text('Item Three')),
            new CheckedPopupMenuItem<String>(
                checked: false, value: 'value04', child: new Text('I am Item Four'))
          ],
      onSelected: (String value) {
        setState(() { _bodyStr = value; });
      });
}

PopupMenuDivider 分割线

      PopupMenuDivider 是一条水平分割线,注意数组要使用父类 PopupMenuEntry,配合其他 item 样式共同使用。PopupMenuDivider 可以调整高度,但无法调整颜色,有需要的话可以进行自定义。

Widget _DividerPopMenu() {
  return new PopupMenuButton<String>(
      itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
            new PopupMenuItem<String>( value: 'value01', child: new Text('Item One')),
            new PopupMenuDivider(height: 1.0),
            new PopupMenuItem<String>( value: 'value02', child: new Text('Item Two')),
            new PopupMenuDivider(height: 1.0),
            new PopupMenuItem<String>( value: 'value03', child: new Text('Item Three')),
            new PopupMenuDivider(height: 1.0),
            new PopupMenuItem<String>( value: 'value04', child: new Text('I am Item Four'))
          ],
      onSelected: (String value) {
        setState(() { _bodyStr = value; });
      });
}

showMenu 指定位置

      PopupMenu 默认的弹框位置都是在右上角,且会挡住标题栏,如果有需要在其他位置弹框就需要借助 showMenu,主要通过 position 属性定位弹框位置。

      menu 的宽高与内容相关,小菜的理解是在水平和竖直方向上会将设置的 position 位置加上 menu 宽高,再与屏幕匹配,超过屏幕宽高,根据 position 按照 LTRB 顺序贴近屏幕边框展示。

onTap: () async {
  final result = await showMenu(
    context: context,
    position: RelativeRect.fromLTRB(100.0, 200.0, 100.0, 100.0),
//    position: RelativeRect.fromLTRB(1000.0, 1000.0, 0.0, 10.0),
    items: <PopupMenuItem<String>>[
      new PopupMenuItem<String>( value: 'value01', child: new Text('Item One')),
      new PopupMenuItem<String>( value: 'value02', child: new Text('Item Two')),
      new PopupMenuItem<String>( value: 'value03', child: new Text('Item Three')),
      new PopupMenuItem<String>( value: 'value04', child: new Text('I am Item Four'))
    ] );
},

      Tips: 如果 item 个数过多也无需担心,Flutter 支持默认超过屏幕滑动效果。


      小菜目前的学习还仅限于基本的使用,稍高级的自定义涉及较少,如果又不对的地方还希望多多指出。

来源:阿策小和尚

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 197,000评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,825评论 2 374
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 144,055评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,766评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,639评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,453评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,860评论 3 388
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,492评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,783评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,817评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,624评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,439评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,872评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,075评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,372评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,868评论 2 343
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,075评论 2 338

推荐阅读更多精彩内容

  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,331评论 0 17
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,709评论 1 92
  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    X先生_未知数的X阅读 15,962评论 3 119
  • Content: Flutter框架概况发展概述发展历史框架特性框架结构 快速入门安装Flutter在Mac OS...
    EchoZuo阅读 6,444评论 3 54
  • 大半夜顾不上擦干脸上的泪水迫不急待的跑来和大家分享一部好片《一年级生》。 电影开头犹如安魂曲般清澈平静的声音就抹平...
    神奇小瘪斯阅读 307评论 0 0