考虑我有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行为?
答案 0 :(得分:0)
将您的小部件树包装在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
的当前值进行条件路由。这只是switch
或您的onWillPop
中的某件事,因此,我将留给您。
不幸的是,它是如此的回旋处,但现在看来这可能是您最好的选择。希望对您有帮助!