flutter - 类似于 Flutter 中的条件路由?
问题描述
考虑我有 3 个屏幕,即屏幕 1、屏幕 2、屏幕 3 和屏幕 4。
我想实现以下目标。
Screen 3 is opened by Screen 1 -> BackButton -> Screen 2
Screen 3 is opened by Screen 2 -> BackButton -> Screen 3
Screen 3 is opened by Screen 4 -> BackButton -> Screen 1
此外,iOS 会自动设置向后滑动选项。我想覆盖它,iOS 中的滑动与上述相同。
Flutter 中是否有类似条件路由的东西,它可以帮助我根据“我的当前屏幕从哪个屏幕打开(navigator.push)”来调整 BackButton 行为?
解决方案
将小部件树包装在小WillPopScope()
部件中。这个小部件有一个onWillPop
属性,你可以覆盖任何你想要的东西——在这种情况下,根据你所在的屏幕,你可能想要覆盖它
onWillPop: () => Navigator.pushReplacement(<correctScreenWidget>)
这应该捕获任何返回的尝试,而是执行您覆盖它的任何操作。小心点,如果做得不好,覆盖默认的后退按钮行为可能会导致奇怪的用户体验。
至于它的条件部分,不幸的是它有点棘手,因为它Navigator._history
是私有的,所以我们不能只检查以前的路线。最好的办法是设置一个NavigatorObserver
来跟踪以前的路线,并在RouteSettings
你的每条路线中设置名称来跟踪。
第一步是创建一个观察者并将其提供给您的Navigator
,如下所示:
class PreviousRouteObserver extends NavigatorObserver {
Route _previousRoute;
Route get previousRoute => _previousRoute;
String get previousRouteName => _previousRoute.settings.name;
@override
void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
_previousRoute = previousRoute;
}
@override
void didReplace({Route<dynamic> newRoute, Route<dynamic> oldRoute}) {
_previousRoute = oldRoute;
}
}
class MyApp extends StatelessWidget {
final PreviousRouteObserver observer = PreviousRouteObserver();
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(title: 'Flutter Demo Home Page', observer: observer),
navigatorObservers: [
observer,
],
);
}
}
请注意,MyHomePage
上面需要接受观察者作为参数,以便您可以访问它。或者,您可以设置一个InheritedWidget
或其他东西来保持对它的访问,但是这个答案已经有点长了,所以我将把它留到后面的问题。
然后,在提供Routes
给您的导航器时,请确保您在以下位置有一个名称RouteSettings
:
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => NextScreen(observer: widget.observer),
settings: RouteSettings(name: "nextScreen"),
),
);
widget.observer.previousRouteName
最后,根据可以访问它的任何小部件中的当前值进行条件路由。这只是你的 aswitch
或某事的简单问题onWillPop
,所以我将把它留给你。
有点不幸的是它是如此迂回,但看起来这可能是你目前最好的选择。希望能帮助到你!
推荐阅读
- react-native - ReactNative 地图视图:标记未在 IOS 上显示
- javascript - 从javascript中的对象数组形成嵌套树
- reactjs - 如何向 eslint 添加规则以检查 camelCase 文件夹名称?
- javascript - Javascript 单元测试 - 在 Promise 链的 .then() 中等待回调触发 - Mocha、Chai、Sinon
- android - 诱骗应用程序认为 ADB 调试已关闭
- visual-studio-code - 无法将属性添加到 COLLAPSED_HIGHLIGHTED_VISUAL_DECORATION
- c++ - 如何在 C++ 中拆分相邻的数字和字母?
- r - 如何在R中的特定日期之前生成表格
- apache-spark - 使用 Spark 2 和 Kafka 2.1 进行 Spark Streaming
- reactjs - 如何在 Autocomplete Material-UI 组件中集成 Number Mask?