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
相关产品推荐
相关产品推荐

