Flutter中使用navigatorKey导航时如何向目标页面传递参数
报错根因
异常原文:
Unhandled Exception: Navigator operation requested with a context that does not include a Navigator.
异常含义:调用导航操作时使用的Context对象,并未被包含在任何Navigator组件的子组件树中。
触发这个异常的原因是:BlocListener回调持有的context属于MaterialApp的builder层级,位置在MaterialApp内部生成的Navigator组件的外层,本身不在Navigator的子组件树范围内,用这个context调用Navigator.of()自然无法匹配到有效的Navigator实例,这也是你单独使用_navigator执行导航时不会报错的原因。
你通过全局_navigatorKey获取_navigator来做导航的模式是完全正确的,要在导航时向下一个页面传递参数,只需要在各页面定义静态路由构造方法时,把参数作为方法入参透传即可,全程不需要依赖会触发异常的context:
- 改造目标页面的静态
route方法,定义需要接收的参数入参
以你要把state.user传递给Home页为例,改造后的Home页代码示例:class Home extends StatelessWidget { // 定义页面需要接收的参数 final User currentUser; const Home({Key? key, required this.currentUser}) : super(key: key); // 改造静态路由方法,将参数作为入参透传到路由构造逻辑中 static Route<void> route(User currentUser) { return MaterialPageRoute<void>( builder: (context) => Home(currentUser: currentUser), ); } } - 调整导航调用逻辑,在调用
_navigator方法时,把Bloc状态中获取到的参数传给改造后的route方法
对应你代码中认证成功分支的改造:case AuthenticationStatus.authenticated: // 直接将state.user作为参数传入Home.route() _navigator.pushAndRemoveUntil<void>( Home.route(state.user), (route) => false, ); break;
注意事项
- AuthPage、SplashPage如果后续需要传递参数,直接复用同样的逻辑:给各自的静态
route方法增加对应入参,构造路由时把参数传递给页面构造函数即可,不需要修改导航调用的核心逻辑。 - 如果后续使用命名路由模式传参,可以直接调用
_navigator.pushNamed('/home', arguments: state.user),在onGenerateRoute回调中通过RouteSettings.arguments读取参数,绑定到对应页面的构造函数上,依然不需要使用会触发异常的context调用导航方法。
内容的提问来源于stack exchange,提问作者Shruti Ramnandan Sharma
相关产品推荐
相关产品推荐

