GoRouter中StatefulShellRoute.indexedStack结合pushNamed控制BottomNavigationBar显隐
解决方案
核心思路
把createClub设为clubview所在StatefulShellBranch的子路由,用pushNamed在当前tab的路由栈内跳转,同时通过判断当前路由是否为分支根页面来控制BottomNavigationBar的显示/隐藏。
步骤1:调整路由配置
将createClub嵌套到clubview的路由下,确保它属于clubview所在的tab栈:
final GoRouter _router = GoRouter( routes: [ StatefulShellRoute.indexStack( builder: (context, state, navigationShell) { // 判断当前是否在分支根页面,决定是否显示底部导航栏 bool showBottomNav = navigationShell.currentBranch?.routes.first.path == navigationShell.currentLocation.path; return Scaffold( body: navigationShell, bottomNavigationBar: showBottomNav ? BottomNavigationBar( items: const [ BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'), BottomNavigationBarItem(icon: Icon(Icons.group), label: '俱乐部'), ], currentIndex: navigationShell.currentIndex, onTap: (index) { navigationShell.goBranch( index, initialLocation: index == navigationShell.currentIndex, ); }, ) : null, ); }, branches: [ // 其他tab分支示例 StatefulShellBranch( routes: [ GoRoute( path: '/home', name: 'home', builder: (context, state) => const HomePage(), ), ], ), // 俱乐部tab分支 StatefulShellBranch( routes: [ GoRoute( path: '/clubview', name: 'clubview', builder: (context, state) => const ClubView(), // 嵌套createClub子路由 routes: [ GoRoute( path: 'createClub', name: 'createClub', builder: (context, state) => const CreateClub(), ), ], ), ], ), ], ), ], );
步骤2:在ClubView中正确跳转
用context.pushNamed替代goNamed,在当前tab的路由栈中添加页面,而非替换整个栈:
// ClubView内的跳转代码 ElevatedButton( onPressed: () { context.pushNamed('createClub'); }, child: const Text('创建俱乐部'), )
步骤3:从CreateClub返回
直接用Navigator.pop(context)即可回到ClubView,因为createClub是当前tab栈的子页面:
// CreateClub内的返回代码 ElevatedButton( onPressed: () { Navigator.pop(context); }, child: const Text('返回'), )
为什么之前的方法失效?
goNamed会直接切换到目标路由并替换整个路由栈,导致ClubView被移出栈,自然无法通过pop返回;- 如果把createClub设为全局路由,它不属于任何StatefulShellBranch的栈,StatefulShellRoute会认为仍在原tab分支,底部导航栏不会自动隐藏。
内容的提问来源于stack exchange,提问作者Miguel Borges
相关产品推荐
相关产品推荐

