使用ShellRoute时context.push无法跳转子路由的问题求助
问题描述
我正在使用Flutter开发一款睡眠分析应用,刚采用go_router管理路由。主界面是带有嵌套导航栏的4个页面,部分路由包含子路由,比如属于ShellRoute的/settings路由下有/settings/profile、/settings/password等子路由。但我无法通过context.push('/settings/my_subroute')实现跳转,context.go则可以正常工作。我需要通过push实现带返回按钮的页面跳转,以下是我的router.dart代码:
final GoRouter router = GoRouter( initialLocation: '/auth', routes: [ ShellRoute( builder: (context, state, child) { return const BottomNavBar(); }, routes: <RouteBase>[ GoRoute( name: 'home', path: '/', builder: (context, state) => const HomeScreen(), ), GoRoute( name: 'sleep', path: '/sleep', builder: (context, state) => const SleepScreen(), ), GoRoute( name: 'dreams', path: '/dreams', builder: (context, state) => const DreamsScreen(), routes: <RouteBase>[ GoRoute( path: 'add', builder: (context, state) => const AddDreamScreen(), ), ], ), GoRoute( name: 'settings', path: '/settings', builder: (context, state) => const SettingsMainScreen(), routes: <RouteBase>[ GoRoute( name: 'profile', path: 'profile', builder: (context, state) => const SettingsProfileScreen(), ), GoRoute( name: 'email', path: 'email', builder: (context, state) => const SettingsEmailScreen(), ), GoRoute( name: 'password', path: 'password', builder: (context, state) => const SettingsPasswordScreen(), ), ], ), ], ), ], );
我怀疑是ShellRoute导致的上下文问题,也不确定是否支持该用法,请问如何让context.push生效?
解决方案
1. 修复ShellRoute的上下文传递(核心问题)
你的ShellRoute构建时没有将child参数传递给BottomNavBar,导致子路由的导航上下文无法正确关联到ShellRoute的嵌套栈中。这是push失效的主要原因。
修改ShellRoute的builder:
ShellRoute( builder: (context, state, child) { return BottomNavBar(child: child); // 移除const,传入child参数 }, // 其余路由配置不变 )
同步修改BottomNavBar的定义,接收并显示传入的child:
class BottomNavBar extends StatelessWidget { final Widget child; const BottomNavBar({super.key, required this.child}); @override Widget build(BuildContext context) { return Scaffold( body: child, // 用这个child显示当前路由的页面内容 bottomNavigationBar: BottomNavigationBar( // 你的导航栏项和切换逻辑 ), ); } }
2. 使用正确的跳转方式
修复上下文后,选择以下两种方式实现push跳转:
- 相对路径跳转:在
SettingsMainScreen内直接使用相对路径:context.push('profile'); // 等价于 /settings/profile - 命名路由跳转:利用路由的name属性,避免路径拼写错误:
context.pushNamed('profile');
3. 区分push和go的使用场景
push:用于在当前页面栈顶部添加新页面(比如从设置主页面进入个人资料页,需要返回按钮)go:用于替换整个页面栈(比如底部导航栏切换页面,不需要返回上一个导航项页面)
内容的提问来源于stack exchange,提问作者user21908253
相关产品推荐
相关产品推荐

