You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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;
                          }
                        },
                      ),
                    ),
                  ),
                ],
              ),
            )
          ],
        ),
      ),
    ),
  ),
)

关键说明

  1. 原生组件适配:PopupMenuButton是Flutter官方提供的Material风格溢出菜单组件,会自动适配Material 3的视觉规范,无需额外自定义样式。
  2. 功能迁移:移除原单独的Daily Goals和Analytics按钮,将它们的点击逻辑迁移到PopupMenuButton的onSelected回调中,通过value区分不同选项。
  3. 体验保留:保留了Tooltip和Semantics组件,确保无障碍访问体验;菜单选项中加入图标和文字,完全匹配Material 3的设计风格。
  4. 样式优化:可选通过shape属性设置圆角,进一步贴合Material 3的设计细节。

内容的提问来源于stack exchange,提问作者pomoworko.com

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 19:55:13