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

2,528

Solution 1

I have solved the problem by using the MaterialPageRoute and referred this link to get the solution Click here

From A->B->C->D screen navigation, I have used this approach

From A->B screen

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

And from B->C, I haved used this along with parameters like below

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

From C->D screen

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

And main logic is here navigations from D->A or D->B, from below liens of code

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

At the last one more thing which I need to add here is that when I want to perform any action like refresh activity and anything else from screen D->A Then inside the A screen, we need to use then method like below

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
        });

Solution 2

If you are using the following code to pop until the route "/A" using Navigator.popUntil method then you should have to set your opening screen with the help of "initialRoute" property in your MaterialApp Widget instead of "home" property.

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"

Also, you can set it with "/" route in your routes property as Follow,

initialRoute : "A",

OR

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

Every thing other is fine in your code.

Share:
2,528
Ravindra Kushwaha
Author by

Ravindra Kushwaha

Contact email - [email protected] Now at 7th position from the top 10 developers of Madhya Pradesh India 🙂

Updated on December 16, 2022

Comments

  • Ravindra Kushwaha
    Ravindra Kushwaha over 1 year

    I am trying to manage the backstack in Flutter like in Android we manage it from launchMode (eg. SingleTask,SingleTop , Standard etc..) , For it i have tried the Routes in flutter, but did not get the success, please check the below code, which i have tried to achieve the 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();
    
    
      }
    }
    

    I am jumping the screens from A->B->C->D are as follow,
    From A->B , I navigate it like below.

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

    From B->C , I navigate it like below.

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

    And finally, From C->D , I navigate it like below.

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

    As from the above code, I successfully navigated to the A------>D screens and also carrying data successfully.

    But my main concern is that i want to navigate from the D->A or D->B screen using the backstack without opening another screen, So i have tried the below code but it is not working , please check the below code.

    From D->A, I have tried like

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

    And even tried in this manner like below.

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

    I even this way to manage the flow like below

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

    But both are not working properly
    Please check my 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,
                );
              }
    
          )
      );
    }
    

    And getting the following exception from above code like below.

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

    Getting execption while navigate from the D->A

  • Ravindra Kushwaha
    Ravindra Kushwaha over 4 years
    I have already define initial routes SplashScreen in my code, please check it once on top.
  • Ravindra Kushwaha
    Ravindra Kushwaha over 4 years
    What i need to change inside the MaterialApp widget, please help me on it.