ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2020-09-14 07:33:34  阅读:317  来源: 互联网

标签:菜单 Menu value PopupMenuItem PopupMenuButton context child Flutter Text


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

构造函数为

image-20200522160319731

参数说明:

  • 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】:

标签:菜单,Menu,value,PopupMenuItem,PopupMenuButton,context,child,Flutter,Text
来源: https://www.cnblogs.com/mengqd/p/13664727.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有