如何从go_router的StatefulShellRoute分支动态生成BottomNavigationBar项
要实现从StatefulShellRoute的分支动态生成底部导航栏项,核心思路是给每个分支路由添加元数据(meta),然后在Scaffold组件中读取这些元数据生成对应的BottomNavigationBarItem。以下是具体实现方案:
1. 给路由分支添加元数据
在定义StatefulShellRoute的branches时,给每个分支的根路由添加meta字段,存储导航栏需要的图标、标签等信息:
final GoRouter _router = GoRouter( initialLocation: '/a', routes: [ StatefulShellRoute.indexedStack( builder: (context, state, navigationShell) { return ScaffoldWithNavBar(navigationShell: navigationShell); }, branches: [ // 分支A StatefulShellBranch( routes: [ GoRoute( path: '/a', builder: (context, state) => const SectionAScreen(), meta: { 'icon': Icons.home, 'label': 'Section A', }, ), ], ), // 分支B StatefulShellBranch( routes: [ GoRoute( path: '/b', builder: (context, state) => const SectionBScreen(), meta: { 'icon': Icons.work, 'label': 'Section B', }, ), ], ), // 分支C StatefulShellBranch( routes: [ GoRoute( path: '/c', builder: (context, state) => const SectionCScreen(), meta: { 'icon': Icons.tab, 'label': 'Section C', }, ), ], ), ], ), ], );
2. 动态生成BottomNavigationBar项
在ScaffoldWithNavBar中,通过navigationShell.route.branches获取所有分支,遍历读取每个分支根路由的元数据,生成导航栏项:
class ScaffoldWithNavBar extends StatelessWidget { const ScaffoldWithNavBar({ required this.navigationShell, Key? key, }) : super(key: key ?? const ValueKey<String>('ScaffoldWithNavBar')); final StatefulNavigationShell navigationShell; void _onTap(BuildContext context, int index) { // 切换分支并保留页面状态 navigationShell.goBranch( index, initialLocation: index == navigationShell.currentIndex, ); } @override Widget build(BuildContext context) { return Scaffold( body: navigationShell, bottomNavigationBar: BottomNavigationBar( // 动态生成导航栏项 items: navigationShell.route.branches.map((branch) { final routeMeta = branch.routes.first.meta; final iconData = routeMeta?['icon'] as IconData; final label = routeMeta?['label'] as String; return BottomNavigationBarItem( icon: Icon(iconData), label: label, ); }).toList(), currentIndex: navigationShell.currentIndex, onTap: (index) => _onTap(context, index), ), ); } }
关键说明
- 元数据存储:利用GoRoute的
meta字段存放导航栏配置,这是go_router官方推荐的自定义路由数据方式。 - 分支遍历逻辑:
navigationShell.route.branches返回所有分支路由,每个分支的routes.first即为该分支的根路由,直接读取其meta即可拿到配置信息。 - 状态保留:使用
navigationShell.goBranch切换分支,确保各分支页面的状态被正确保留,符合StatefulShellRoute的设计初衷。
内容的提问来源于stack exchange,提问作者john
相关产品推荐
相关产品推荐

