像Flutter中的条件路由一样?

时间:2019-02-21 10:54:23

标签: 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行为?

1 个答案:

答案 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中的某件事,因此,我将留给您。

不幸的是,它是如此的回旋处,但现在看来这可能是您最好的选择。希望对您有帮助!