In Flutter using the go_router library I am adding pages A, B and C, which exist in a BottomNavBar navigation. They are all encapsulated in a ShellRoute with a BottomNavBar and work like a charm.
My question is how can I add this BottomNavBar to a new screen D, which is not in the Shell list?
Just by adding the D route to the ShellRoute, I get the NavBar, but I cannot navigate to A (the first index), because it's selected by default.
I am using Flutter 3.7.5 with go_router 6.2.0, which I pass to a MaterialApp.router.
ShellRoute:
ShellRoute(
navigatorKey: _shellNavigatorKey,
builder: (context, state, child) {
return ScaffoldWithBottomNavBar(child: child);
},
routes: [
GoRoute(
path: '/a',
builder: (context, state) => const A(),
),
GoRoute(
path: '/b',
builder: (context, state) => const B(),
),
GoRoute(
path: '/c',
builder: (context, state) => const C(),
),
GoRoute(
path: '/d',
builder: (context, state) => const D(),
),
]
),
Scaffolded BottomNavBar:
class _ScaffoldWithBottomNavBarState extends State<ScaffoldWithBottomNavBar> {
int get _currentIndex => _locationToTabIndex(GoRouter.of(context).location);
int _locationToTabIndex(String location) {
final index = tabs.indexWhere((t) => location.startsWith(t.route));
// if index not found (-1), return 0
return index < 0 ? 0 : index;
}
// callback used to navigate to the desired tab
void _onItemTapped(BuildContext context, int tabIndex) {
// The problem occurs here - on screen D
// _currentIndex == A and we don't navigate to A
if (tabIndex != _currentIndex) {
context.go(tabs[tabIndex].route);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: widget.child,
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
items: tabs,
onTap: (index) => _onItemTapped(context, index),
),
);
}
}
Update
After doing a research and brainstorming, my conclusion is that screens that are not in the NavBar items shouldn't have a NavBar in the first place. They act like a modal and have a back button instead.