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

Flutter中如何实现每个menu菜单项点击跳转至对应独立页面

菜单运行效果截图

问题说明

当前实现的列表菜单所有选项点击后都会跳转至同一个prendrerdv页面,需要为不同菜单项配置独立的点击跳转逻辑,点击后打开对应页面。

问题根因

封装的menu组件把点击跳转逻辑硬编码在内部,所有调用该方法生成的菜单项,GestureDetector的onTap回调都固定执行跳转到prendrerdv的代码,没有对外暴露自定义点击事件的入口。

修改方案

给menu方法新增一个必填的点击回调参数,每个菜单项调用时单独传入自己的跳转逻辑即可,具体改动点:

  • 给menu方法增加VoidCallback类型的必填参数onTap,用来接收外部传入的自定义点击事件
  • 将menu组件内部GestureDetector的onTap逻辑替换为调用外部传入的onTap回调
  • 每个菜单项调用menu方法时,单独传入对应页面的跳转代码
  • 补全原方法缺失的第一个参数类型声明,原代码中IDIconData没有指定类型,会触发类型报错,统一补为IconData类型,和传入的Material图标类型匹配
修改后完整代码
Expanded(
  child: Container(
    margin: EdgeInsets.only(left: 20, right: 20),
    child: ListView(
      children: [
        // 预约入口
        menu(
          Icons.account_circle,
          "Prendre un rendez-vous",
          onTap: () {
            Navigator.push(context, MaterialPageRoute(builder: (context) => prendrerdv()));
          },
        ),
        // 资格测试入口
        menu(
          Icons.account_circle,
          "Tester l'éligibilité",
          onTap: () {
            // 把下面的类名替换成你项目中实际的资格测试页面类
            Navigator.push(context, MaterialPageRoute(builder: (context) => EligibilityPage()));
          },
        ),
        // 中心定位入口
        menu(
          Icons.account_circle,
          "Géo-localisation des centres",
          onTap: () {
            // 替换成你项目中实际的定位页面类
            Navigator.push(context, MaterialPageRoute(builder: (context) => CenterLocationPage()));
          },
        ),
        // 拍照入口
        menu(
          Icons.account_circle,
          "Capturer le moment",
          onTap: () {
            // 替换成你项目中实际的拍照页面类
            Navigator.push(context, MaterialPageRoute(builder: (context) => CapturePage()));
          },
        ),
        // 捐赠者社群入口
        menu(
          Icons.account_circle,
          "Rejoindre des donneurs",
          onTap: () {
            // 替换成你项目中实际的捐赠者社群页面类
            Navigator.push(context, MaterialPageRoute(builder: (context) => DonorGroupPage()));
          },
        ),
      ],
    ),
  ),
),

// 修改后的menu组件
Widget menu(IconData IDIconData, String name, {required VoidCallback onTap}) {
  return GestureDetector(
    onTap: onTap,
    child: Container(
      height: 90,
      margin: EdgeInsets.only(top: 10),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(5),
      ),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Container(
            margin: EdgeInsets.only(left: 20, top: 10),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisAlignment: MainAxisAlignment.start,
              children: [
                Container(
                  margin: EdgeInsets.only(top: 30),
                  child: Text(
                    name,
                    style: const TextStyle(
                      color: Color(0xff363636),
                      fontSize: 17,
                      fontFamily: 'Roboto',
                      fontWeight: FontWeight.w700,
                    ),
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    ),
  );
}

注:原代码中menu方法里声明的size变量没有被实际使用,已删掉冗余代码。如果后续需要给不同菜单项配置不同图标,直接替换调用menu时第一个传入的Icons.xxx图标值即可。

内容的提问来源于stack exchange,提问作者Nizar Loutra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 20:03:21