Flutter :- 如何像 Android "SingleTask" 那样管理后台堆栈?

Flutter :- How manage the backstack like in Android "SingleTask"?

我正在尝试管理 Flutter 中的 backstack,就像在 Android 中一样,我们从 launchMode (eg. SingleTask,SingleTop, Standard etc..) ,为此我在 flutter 中尝试了 Routes,但没有成功,请检查下面的代码,我已尝试实现 backstack.

Widget makeRoute(
    {@required BuildContext context,
    @required String routeName,
    Object arguments}) {
  final Widget child =
      _buildRoute(context: context, routeName: routeName, arguments: arguments);
  return child;
}

Widget _buildRoute({
  @required BuildContext context,
  @required String routeName,
  Object arguments,
}) {
  switch (routeName) {
    case '/':
      return SplashScreen();

    case '/A':              //// NAME OF SCREEN IS A
      return A();

    case '/B':              //// NAME OF SCREEN IS B
      MyBean docs = arguments as MyBean;
      return B(dataToShow: docs);

    case '/C':              //// NAME OF SCREEN IS C
      MyBean docs = arguments as MyBean;
      return C(dataToShow: docs);

    case '/D':             //// NAME OF SCREEN IS D
      return D();


  }
}

我从A->B->C->D跳屏如下,
从 A->B ,我按如下方式导航。

Navigator.of(context).pushNamed('/B');

从 B->C 开始,我按如下方式导航。

 Navigator.of(context).pushNamed('/C', arguments: myList[index]);

最后,从 C->D 开始,我按如下方式导航。

Navigator.of(context).pushNamed('/D');

从上面的代码,我成功导航到A------>D屏幕,也成功携带数据。

但我主要担心的是我想在不打开另一个屏幕的情况下使用后台从 D->A 或 D->B 屏幕导航,所以我尝试了下面的代码但是 它不工作,请检查下面的代码。

从D->A,我试过像

Navigator.popUntil(context, ModalRoute.withName('/A'));

甚至像下面这样尝试过。

 Navigator.of(context)
          .popUntil(ModalRoute.withName("/A"));

我什至像下面这样管理流程

 SchedulerBinding.instance.addPostFrameCallback((_) {
                      Navigator.popUntil(context, ModalRoute.withName('/A'));

                    });

但两者都无法正常工作
请检查我的 main() class

void main() {
  runApp(
      MaterialApp(
        debugShowCheckedModeBanner: false,
        title: '',
        theme: ThemeData(
          brightness: Brightness.light,
          primarySwatch: Colors.grey,
          primaryColor: ColorConst.PRIMARY_COLOR,
          accentColor: ColorConst.ACCENT_COLOR,
          primaryColorBrightness: Brightness.light,


          accentColorBrightness: Brightness.light,
        ),

          onGenerateRoute: (RouteSettings settings) {
            return MaterialPageRoute(
              builder: (BuildContext context) => makeRoute(
                context: context,
                routeName: settings.name,
                arguments: settings.arguments,
              ),
              maintainState: true,
              fullscreenDialog: false,
            );
          }

      )
  );
}

并从上面的代码中获取以下异常。

═ (2) Exception caught by widgets library ═══════════════════════════════════════════════════
'package:flutter/src/widgets/navigator.dart': Failed assertion: line 2330 pos 12: '!_debugLocked': is not true.
The relevant error-causing widget was: 
  MaterialApp **file:///Users/apple/Documents/BitBucket%20Projects/loyalityapp_android/lib/main.dart:10:7**
════════════════════════════════════════════════════════════════════════════════════════════════════

如果您使用以下代码使用 Navigator.popUntil 方法弹出直到路由“/A”,那么您应该在 [=28= 的帮助下设置您的开始屏幕] 属性 在您的 MaterialApp 小部件中 而不是 "home" 属性。

Navigator.popUntil(context, ModalRoute.withName('/A'));

Because, here you are navigating to the route "A" with the help of "push navigator routes" and want to pop using "named routes"

此外,您可以在您的路线中使用“/”路线设置它属性作为Follow,

initialRoute : "A",

routes:{
          "/": (context)=> A(),
}

您的代码中的其他一切都很好。

我已经使用 MaterialPageRoute 解决了这个问题,并引用了这个 link 来获得解决方案

从A->B->C->D画面导航,我都用过这种做法

从A->B屏幕

 Navigator.push(
                    context,
                    MaterialPageRoute(
                      settings: RouteSettings(name: "B"),
                      builder:  (context) => SCREEN_B(),
                    ),
                  );

从 B->C,我使用了它以及如下参数

 Navigator.push(
              context,
              MaterialPageRoute(
                settings: RouteSettings(name: "C"),
                builder:  (context) => SCREEN_C(dataToShow:myList[index]),
              ),
            );

从 C->D 屏幕

 Navigator.push(
                    context,
                    MaterialPageRoute(
                      settings: RouteSettings(name: "D"),
                      builder:  (context) => SCREEN_D(),
                    ),
                  );

这里的主要逻辑是从 D->A 或 D->B 的导航,从下面的代码留置权

Navigator.popUntil(context, ModalRoute.withName("A"));  //YOU CAN USE "B" TO NAVIGATE

最后一件事我需要在此处添加的是,当我想执行任何操作(如刷新 activity 以及屏幕 D->A 中的任何其他操作时 然后在A屏里面,我们需要使用下面的then方法

Navigator.push(
          context,
          MaterialPageRoute(
            settings: RouteSettings(
                name: "B"),
            builder: (context) =>
                B(dataToShow: MYLIST[index]),
          ),
        ).then((value) {
          //// THIS METHOD IS ENVOKE WHEN SCREEN COME FROM D->A OR B->A, YOU CAN PERFROM CAN TASK HERE
        });