如何从 NavigatorObserver 更新底部导航栏的状态?

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

我正在创建一个底部导航栏并且一切正常,除非用户按下他们设备上的后退按钮。导航栏的状态不会更新以反映它们所在的页面。为了解决这个问题,我发现了 NavigatorObserver。现在我可以看到一条路线何时弹出,但我无法更新状态。我的导航栏使用路线,所以当用户点击一个按钮时,它会推送一条新路线。我正在尝试更新导航栏的索引,但我看不到这样做的方法。导航栏正在使用 StatefulWidget,因此我可以使用 setState 回调。

我试过使用密钥,但我无法重复使用它们,因为它们位于不同的 Scaffolds 上。我无法从 NavigationObserver 访问 BuildContext,所以我无法使用 Provider 之类的东西来通知更改和重建。

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;
    }
  }
}

您可以通过多种方式进行。这里我举了一个 ValueNotifier 的例子。首先,您可以创建一个枚举来定义底部导航栏的不同页面。然后你用你的枚举类型创建一个 ValueNotifier 并在 NavBarObserverCustomBottomNavBar 之间共享它。在 NavBarObserver 中,当发生任何选项卡更改时,您只需使用相应选项卡的枚举值更新 ValueNotifier 值。您可以在 _CustomBottomNavBarState 中监听 ValueNotifier 值变化以更新底部导航栏状态。

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;
    }
  }
}