如何在StatefulShellBranch子树中推送全屏页面并复用Bloc状态
解决GoRouter StatefulShellRoute分支内详情页全屏并复用Bloc状态的问题
要实现/c分支下的详情页全屏显示(不被底部导航栏包裹)同时复用ScaffoldWithNavBar中注入的Bloc状态,核心是让详情页使用根导航器而非分支导航器,同时保留Bloc的上下文可达性,具体操作如下:
关键思路
StatefulShellRoute的builder是在根导航器的上下文下渲染的,你在这里注入的Bloc会被根上下文持有。只要让详情页使用根导航器(_rootNavigatorKey),就能既跳出底部导航栏的包裹,又能访问到根上下文里的Bloc实例。
修改步骤
给/c分支的详情路由添加parentNavigatorKey: _rootNavigatorKey配置,让它使用根导航器推送页面:
final GlobalKey<NavigatorState> _rootNavigatorKey = GlobalKey<NavigatorState>(debugLabel: 'root'); final GoRouter _router = GoRouter( navigatorKey: _rootNavigatorKey, initialLocation: '/a', routes: <RouteBase>[ StatefulShellRoute.indexedStack( builder: (BuildContext context, GoRouterState state, StatefulNavigationShell navigationShell) { // **Inject Bloc!!** return ScaffoldWithNavBar(navigationShell: navigationShell); }, branches: <StatefulShellBranch>[ // ... 其他分支保持不变 StatefulShellBranch( routes: <RouteBase>[ GoRoute( path: '/c', builder: (BuildContext context, GoRouterState state) => const RootScreen( label: 'C', detailsPath: '/c/details', ), routes: <RouteBase>[ GoRoute( path: 'details', // 重点:指定使用根导航器 parentNavigatorKey: _rootNavigatorKey, builder: (BuildContext context, GoRouterState state) => DetailsScreen( label: 'C', extra: state.extra, ), ), ], ), ], ), ], ), ], );
效果说明
- 推送
/c/details时,页面会通过根导航器展示,完全脱离ScaffoldWithNavBar的底部导航栏,实现全屏。 - 详情页的
context可以直接获取到StatefulShellRoute builder中注入的Bloc,因为根导航器的上下文包含该BlocProvider。
这样既保持了路由在/c分支内的结构,又满足了全屏和状态复用的需求。
内容的提问来源于stack exchange,提问作者Get Malone
相关产品推荐
相关产品推荐

