简体   繁体   中英

How to update the state of a bottom navigation bar from NavigatorObserver?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM