flutter - Flutter Navigator popUntilOrPush
问题描述
想象一下,您有一个BottomNavigationBar
带有 4 个图标的图标,可以导航到 4 个屏幕。当我这样做时:
A > B > D > B
我希望正常行为会弹出到第一个 B,这使我的堆栈只剩下 A > B。popUntil()
我可以做到这一点。但是,当使用popUntil()
and B 在堆栈中不存在时,它会弹出整个堆栈。pushNamed()
相反,如果 B 不存在,我想这样做。由于我无权访问堆栈历史记录,我该怎么做?
@GrahamD 你是对的,我编辑了它。
解决方案
使用@GrahamD 的建议,这是我目前的导航配置,对我来说似乎有点 hacky 但有效:
main.dart
...
return MaterialApp(
navigatorObservers: [NavObserver()],
navigatorKey: serviceLocator<NavigationService>().navigatorKey,
onGenerateRoute: Router().generateRoute,
...
navigation_service.dart
class NavigationService {
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
List<AppRoute> routeStack = [];
///navigate to destination and add destination to stack
void navigateTo(AppRoute destination, {Object arguments}) {
if (routeStack.isEmpty || routeStack.last != destination) {
navigatorKey.currentState
.pushNamed(destination.index.toString(), arguments: arguments);
}
}
///pushNamedAndRemoveUntil and add destination to stack after clearing it
void pushNamedAndRemoveUntil(AppRoute route, {Object arguments}) {
navigatorKey.currentState.pushNamedAndRemoveUntil(
route.index.toString(), (route) => false,
arguments: arguments);
}
///pop
void pop({Object arguments}) {
return navigatorKey.currentState.pop(arguments);
}
///if the route exists in the stack, popUntil, otherwise pushNamed
void popUntilOrPush(AppRoute route) {
if (routeStack.contains(route)) {
return navigatorKey.currentState
.popUntil(ModalRoute.withName(route.index.toString()));
} else {
navigateTo(route);
}
}
}
class NavObserver extends NavigatorObserver {
final navService = serviceLocator<NavigationService>();
@override
void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
if (route.settings.name == "/") {
//initial route is provided by the app
navService.routeStack.add(AppRoute.Home);
} else {
navService.routeStack
.add(AppRoute.values[int.parse(route.settings.name)]);
}
}
@override
void didStopUserGesture() {}
@override
void didStartUserGesture(
Route<dynamic> route, Route<dynamic> previousRoute) {}
@override
void didReplace({Route<dynamic> newRoute, Route<dynamic> oldRoute}) {}
@override
void didRemove(Route<dynamic> route, Route<dynamic> previousRoute) {
navService.routeStack.lastWhere((AppRoute appRoute) => route.settings.name == appRoute.index.toString());
}
@override
void didPop(Route<dynamic> route, Route<dynamic> previousRoute) {
navService.routeStack.removeLast();
}
}
class Router {
final nav = serviceLocator<NavigationService>();
Route<dynamic> generateRoute(RouteSettings settings) {
final AppRoute appRoute = AppRoute.values[int.parse(settings.name)];
switch (appRoute) {
case AppRoute.AuthLogin:
return PageRouteBuilder(
settings: settings,
pageBuilder: (_, __, ___) =>
AuthScreen(dynamicLink: settings.arguments));
case AppRoute.AuthEmail:
return PageRouteBuilder(
settings: settings, pageBuilder: (_, __, ___) => EmailScreen());
case AppRoute.Home:
return PageRouteBuilder(
settings: settings, pageBuilder: (_, __, ___) => HomeScreen());
case AppRoute.Search:
return PageRouteBuilder(
settings: settings, pageBuilder: (_, __, ___) => SearchScreen());
case AppRoute.PublishGallery:
return PageRouteBuilder(
settings: settings,
pageBuilder: (_, __, ___) => PublishGalleryScreen());
case AppRoute.Notifications:
return PageRouteBuilder(
settings: settings,
pageBuilder: (_, __, ___) => NotificationsScreen());
case AppRoute.Profile:
return PageRouteBuilder(
settings: settings, pageBuilder: (_, __, ___) => ProfileScreen());
default:
//should never be called
return PageRouteBuilder(
pageBuilder: (_, __, ___) => Scaffold(
body: Center(
child: Text('No route defined for ${settings.name}')),
));
}
}
}
enum AppRoute {
AuthLogin,
AuthEmail,
Wizard,
Home,
Search,
PublishGallery,
Notifications,
Profile
}
推荐阅读
- azure-active-directory - 为什么 Microsoft Dynamics 365 在 Azure 应用注册中要求委派管理员
- python - 执行代码后按下 GPIO 19 时,我应该怎么做才能使其工作?
- c - 为什么中断不是由 C 代码生成,而是由汇编指令轻松生成?
- python-3.x - 如何将 Django 中的日期时间字段转换为被谷歌日历事件接受?
- api - REST API 中使用了哪些协议(HTTP 除外)?
- java - Spring Boot PSQLException:错误:“duration_answer”列中的空值违反非空约束
- postgresql - 错误:无法更改视图或规则使用的列的类型详细信息:视图上的规则 _RETURN 取决于列“状态”
- postgresql - 是否可以使用“生成的列”在 PostgreSQL 中使用“current_timestamp”更新列(自动)?
- javascript - 这个 forEach 循环有什么问题?它不能正常运行
- javascript - Phyton 中的 Dygraph:如何删除标签但仍然在图中使用其值?