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

时间:2020-04-12 14:39:59

标签: flutter state-management

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

我尝试使用键,但是由于它们位于不同的Scaffold上,因此我无法重复使用它们。我无法从BuildContext访问NavigationObserver,所以不能使用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;
    }
  }
}

1 个答案:

答案 0 :(得分:0)

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

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