Flutter命名路由pushNamed传参时ModalRoute获取arguments始终为null
Flutter命名路由传递参数后arguments为null的问题解决
问题成因
排除context使用错误、嵌套Navigator路由混淆的极端情况,90%以上的该类问题都由以下原因导致:
- 项目同时配置了
MaterialApp的routes属性和onGenerateRoute属性,自定义的onGenerateRoute返回路由时,没有将原请求携带的settings参数传入MaterialPageRoute,导致arguments丢失,路由名称因为可直接从原请求读取所以能正常输出。 - 项目完全基于自定义
onGenerateRoute实现路由管理,构造路由时未传入settings参数,ModalRoute自然无法读取到传递的参数。
解决方法
方案1:移除冗余的onGenerateRoute配置
如果不需要自定义路由转场、路由拦截等特殊逻辑,直接删除MaterialApp中的onGenerateRoute配置,仅保留routes表即可。Flutter原生默认路由逻辑会自动传递arguments参数,无需额外处理。
方案2:修正onGenerateRoute逻辑,正确传递settings参数
如果需要保留onGenerateRoute做自定义处理,构造MaterialPageRoute时必须传入原请求的settings参数,示例如下:
MaterialApp( routes: { '/page/one': (context) => ScreenA(), '/page/two': (context) => ScreenB(), '/page/three': (context) => ScreenC(), }, onGenerateRoute: (settings) { // 自定义路由逻辑示例 if (settings.name == '/page/two') { return MaterialPageRoute( builder: (context) => ScreenB(), settings: settings, // 必须添加该行,传递路由参数 ); } // 其余路由走默认routes匹配逻辑 return null; }, )
方案3:构造页面时直接传递参数(备选)
如果不想依赖ModalRoute读取参数,可以直接在路由构造时将参数传递给页面的构造函数:
- 先修改ScreenB增加构造参数:
class ScreenB extends StatelessWidget { final PageArguments arguments; const ScreenB({super.key, required this.arguments}); @override Widget build(BuildContext context) { print(arguments.id); print(arguments.title); return Scaffold(); } }
- 再修改onGenerateRoute逻辑:
onGenerateRoute: (settings) { if (settings.name == '/page/two') { final args = settings.arguments as PageArguments; return MaterialPageRoute( builder: (context) => ScreenB(arguments: args), settings: settings, ); } // 其他路由处理逻辑 return null; }
内容的提问来源于stack exchange,提问作者DolDurma
相关产品推荐
相关产品推荐

