首页 > 解决方案 > 类似于 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 行为?

标签: flutter

解决方案


将小部件树包装在小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,所以我将把它留给你。

有点不幸的是它是如此迂回,但看起来这可能是你目前最好的选择。希望能帮助到你!


推荐阅读