Флаттер: - Как управлять backstack, как в Android «SingleTask»? - PullRequest
1 голос
/ 07 января 2020

Я пытаюсь управлять backstack в Flutter, как в Android, которым мы управляем с launchMode (например, SingleTask, SingleTop, Standard et c. .) , Для этого я попробовал 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 с помощью backstack, не открывая другой экран, поэтому я попробовал приведенный ниже код, но он не работает , пожалуйста, проверьте код ниже.

Из 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() класс

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**
════════════════════════════════════════════════════════════════════════════════════════════════════

imageA">

Ответы [ 2 ]

1 голос
/ 07 января 2020

Я решил проблему с помощью MaterialPageRoute и сослался на эту ссылку, чтобы получить решение Нажмите здесь

От A-> B -> C -> D экранная навигация, я использовал этот подход

С экрана A-> B

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

И из B -> C, я использовал это наряду с параметрами, подобными приведенным ниже Ниже приведены ссылки на код

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

И еще одна вещь, которую мне нужно добавить, это то, что когда я хочу выполнить какое-либо действие, например refre sh активность, и все остальное с экрана 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
        });
1 голос
/ 07 января 2020

Если вы используете следующий код для перемещения до маршрута "/ A" с помощью метода Navigator.popUntil, вам необходимо настроить начальный экран с помощью свойства initialRoute в вашем MaterialApp. Виджет вместо свойства "home" .

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

Потому что здесь вы переходите к маршруту «A» с помощью «pu sh navigator route» и хотите всплыть, используя «именованные маршруты»

Кроме того, вы можете установить его с помощью "/" в свойстве маршрутов как Follow,

initialRoute : "A",

ИЛИ

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

Все остальное хорошо в вашем коде.

...