如何从 NavigatorObserver 更新底部导航栏的状态?
How to update the state of a bottom navigation bar from NavigatorObserver?
我正在创建一个底部导航栏并且一切正常,除非用户按下他们设备上的后退按钮。导航栏的状态不会更新以反映它们所在的页面。为了解决这个问题,我发现了 NavigatorObserver
。现在我可以看到一条路线何时弹出,但我无法更新状态。我的导航栏使用路线,所以当用户点击一个按钮时,它会推送一条新路线。我正在尝试更新导航栏的索引,但我看不到这样做的方法。导航栏正在使用 StatefulWidget
,因此我可以使用 setState
回调。
我试过使用密钥,但我无法重复使用它们,因为它们位于不同的 Scaffold
s 上。我无法从 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
并在 NavBarObserver
和 CustomBottomNavBar
之间共享它。在 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;
}
}
}
我正在创建一个底部导航栏并且一切正常,除非用户按下他们设备上的后退按钮。导航栏的状态不会更新以反映它们所在的页面。为了解决这个问题,我发现了 NavigatorObserver
。现在我可以看到一条路线何时弹出,但我无法更新状态。我的导航栏使用路线,所以当用户点击一个按钮时,它会推送一条新路线。我正在尝试更新导航栏的索引,但我看不到这样做的方法。导航栏正在使用 StatefulWidget
,因此我可以使用 setState
回调。
我试过使用密钥,但我无法重复使用它们,因为它们位于不同的 Scaffold
s 上。我无法从 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
并在 NavBarObserver
和 CustomBottomNavBar
之间共享它。在 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;
}
}
}