I'm creating a bottom navigation bar and everything works fine except when the user presses the back button on their device. The state of the navigation bar doesn't update to reflect the page they're on. To fix this, I found out about NavigatorObserver
. Now I can see when a route gets popped but I have no way of updating the state. My navigation bar uses routes so when a user taps a button, it'll push a new route. I'm trying to update the index of the navigation bar but I can't see a way to do so. The navbar is using a StatefulWidget
so I can use the setState
callback.
I've tried using keys but I can't re-use them since they're on different Scaffold
s. I can't access the BuildContext
from a NavigationObserver
so I can't use things like Provider
to notify a change and to rebuild.
class CustomBottomNavBar extends StatefulWidget {
@override
_CustomBottomNavBarState createState() => _CustomBottomNavBarState();
}
class _CustomBottomNavBarState extends State<CustomBottomNavBar> {
static int _selectedIndex;
int get selectedIndex => _selectedIndex;
set selectedIndex(int newIndex) {
setState(() {
_selectedIndex = newIndex;
});
}
//...
}
class NavBarObserver extends NavigatorObserver {
@override
void didPop(Route route, Route previousRoute) {
final navBarRoutes = Routes.all.sublist(0,4);
final routeName = route.settings.name;
if (navBarRoutes.contains(routeName)) {
final index = navBarRoutes.indexOf(routeName);
// selectedIndex = index;
}
}
}
You can do it couple ways. Here I have given an example with ValueNotifier
. First you can create a enum that define different pages of you bottom navigation bar. Then you create a ValueNotifier
with your enum type and share it between NavBarObserver
and CustomBottomNavBar
. In NavBarObserver
when any tab change occurred you simply updated the ValueNotifier
value with corresponding tab's enum value. You can listen ValueNotifier
value change in _CustomBottomNavBarState
to update the bottom navigation bar state.
enum Tabs{one, two, three}
class CustomBottomNavBar extends StatefulWidget {
final ValueNotifier<Tabs> tabsChangeNotifier;
CustomBottomNavBar(this.tabsChangeNotifier);
@override
_CustomBottomNavBarState createState() => _CustomBottomNavBarState();
}
class _CustomBottomNavBarState extends State<CustomBottomNavBar> {
Tabs _currentTab;
@override
void initState() {
super.initState();
widget.tabsChangeNotifier.addListener(() {
setState(() {
_currentTab = widget.tabsChangeNotifier.value;
});
});
}
}
class NavBarObserver extends NavigatorObserver {
final ValueNotifier<Tabs> tabsChangeNotifier;
NavBarObserver(this.tabsChangeNotifier);
@override
void didPop(Route route, Route previousRoute) {
final navBarRoutes = Routes.all.sublist(0,4);
final routeName = route.settings.name;
if (navBarRoutes.contains(routeName)) {
tabsChangeNotifier.value = Tabs.two;
// selectedIndex = index;
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.