如何在Flutter中将指定图标整合到Material 3风格溢出菜单?
实现Material Design 3风格的Flutter AppBar溢出菜单
我正在开发一款Flutter应用,想要实现Material Design 3风格的溢出菜单(带图标的下拉式菜单样式)。以下是当前我用于创建带多个图标的AppBar的代码片段:
child: Scaffold( appBar: AppBar( backgroundColor: Color.fromARGB(255, 255, 202, 55), title: ResponsiveWeb( child: SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( textDirection: TextDirection.ltr, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( padding: const EdgeInsets.only(left: 8, right: 0), child: Row( children: [ const Icon( FontAwesomeIcons.checkDouble, size: 25, color: const Color(0xff3B3B3B), ), ], ), ), Container( padding: const EdgeInsets.only(left: 8, right: 0), child: Row( children: [ Tooltip( message: 'Daily goals', child: Semantics( label: 'Pomodoro timer daily goals', enabled: true, readOnly: true, child: IconButton( icon: Icon( Icons.military_tech_outlined, color: const Color(0xff3B3B3B), size: 25, semanticLabel: 'Pomodoro timer daily goals', ), onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => SettingsUIPomodoro()), ); }, ), ), ), Tooltip( message: 'Settings', child: Semantics( label: 'Pomodoro timer settings', enabled: true, readOnly: true, child: IconButton( icon: Icon( Icons.settings_outlined, color: const Color(0xff3B3B3B), size: 25, semanticLabel: 'Pomodoro timer Settings', ), onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => SettingsUIPomodoro()), ); }, ), ), ), Tooltip( message: 'Analytics', child: Semantics( label: 'Pomodoro timer Analytics', enabled: true, readOnly: true, child: IconButton( icon: Icon( Icons.show_chart_outlined, color: const Color(0xff3B3B3B), size: 25, semanticLabel: 'Pomodoro timer Analytics', ), onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => Text('goal')), ); }, ), ), ), Tooltip( message: 'Profile', child: Semantics( label: 'Pomodoro timer Profile', enabled: true, readOnly: true, child: IconButton( icon: Icon( Icons.face_outlined, color: const Color(0xff3B3B3B), size: 25, semanticLabel: 'Pomodoro timer Profile', ), onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => Profile()), ); }, ), ), ), Tooltip( message: 'More', child: Semantics( label: 'Pomodoro timer More', enabled: true, readOnly: true, child: IconButton( icon: Icon( Icons.more_vert_outlined, color: const Color(0xff3B3B3B), size: 25, semanticLabel: 'Pomodoro timer More', ), onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => Profile()), ); }, ), ), ), ], ), ) ], ), ), ), ), )
我需要把以下两个图标整合到「More」溢出菜单中,复刻Material 3的设计:
- 'daily goals'图标(
Icons.military_tech_outlined) - 'analytics'图标(
Icons.show_chart_outlined)
修改方案
直接使用Flutter官方的PopupMenuButton组件替换原「More」按钮的IconButton,并将两个目标功能迁移到菜单选项中,修改后的完整代码如下:
child: Scaffold( appBar: AppBar( backgroundColor: Color.fromARGB(255, 255, 202, 55), title: ResponsiveWeb( child: SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( textDirection: TextDirection.ltr, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( padding: const EdgeInsets.only(left: 8, right: 0), child: Row( children: [ const Icon( FontAwesomeIcons.checkDouble, size: 25, color: const Color(0xff3B3B3B), ), ], ), ), Container( padding: const EdgeInsets.only(left: 8, right: 0), child: Row( children: [ Tooltip( message: 'Settings', child: Semantics( label: 'Pomodoro timer settings', enabled: true, readOnly: true, child: IconButton( icon: Icon( Icons.settings_outlined, color: const Color(0xff3B3B3B), size: 25, semanticLabel: 'Pomodoro timer Settings', ), onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => SettingsUIPomodoro()), ); }, ), ), ), Tooltip( message: 'Profile', child: Semantics( label: 'Pomodoro timer Profile', enabled: true, readOnly: true, child: IconButton( icon: Icon( Icons.face_outlined, color: const Color(0xff3B3B3B), size: 25, semanticLabel: 'Pomodoro timer Profile', ), onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => Profile()), ); }, ), ), ), // 替换为PopupMenuButton实现Material 3风格溢出菜单 Tooltip( message: 'More', child: Semantics( label: 'Pomodoro timer More', enabled: true, readOnly: true, child: PopupMenuButton( icon: Icon( Icons.more_vert_outlined, color: const Color(0xff3B3B3B), size: 25, semanticLabel: 'Pomodoro timer More', ), // 适配Material 3的圆角样式 shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), itemBuilder: (context) => [ // Daily Goals菜单选项 PopupMenuItem( value: 'daily_goals', child: Row( children: [ Icon( Icons.military_tech_outlined, color: const Color(0xff3B3B3B), size: 20, ), SizedBox(width: 8), Text('Daily Goals'), ], ), ), // Analytics菜单选项 PopupMenuItem( value: 'analytics', child: Row( children: [ Icon( Icons.show_chart_outlined, color: const Color(0xff3B3B3B), size: 20, ), SizedBox(width: 8), Text('Analytics'), ], ), ), ], onSelected: (value) { // 处理不同菜单选项的跳转逻辑 switch(value) { case 'daily_goals': Navigator.push( context, MaterialPageRoute(builder: (context) => SettingsUIPomodoro()), ); break; case 'analytics': Navigator.push( context, MaterialPageRoute(builder: (context) => Text('goal')), ); break; } }, ), ), ), ], ), ) ], ), ), ), ), )
关键说明
- 原生组件适配:
PopupMenuButton是Flutter官方提供的Material风格溢出菜单组件,会自动适配Material 3的视觉规范,无需额外自定义样式。 - 功能迁移:移除原单独的Daily Goals和Analytics按钮,将它们的点击逻辑迁移到
PopupMenuButton的onSelected回调中,通过value区分不同选项。 - 体验保留:保留了Tooltip和Semantics组件,确保无障碍访问体验;菜单选项中加入图标和文字,完全匹配Material 3的设计风格。
- 样式优化:可选通过
shape属性设置圆角,进一步贴合Material 3的设计细节。
内容的提问来源于stack exchange,提问作者pomoworko.com
相关产品推荐
相关产品推荐

