57

I used Navigator.push up to 6 screens to get to the payment page. After Payment, I want to push to the "Payment Successful" page then remove all the previous screens i.e using the back button will return to the very first screen.

NOTE: I have tried pushReplacementNamed and it doesn't work.

Kingsley CA
  • 10,685
  • 10
  • 26
  • 39
  • No i did'nt. using `pushRepalcementNamed` takes me to a new route, but when I use the back button takes to to the last Named Route instead of the back button not working. – Kingsley CA Oct 07 '18 at 13:47
  • 2
    Perhaps you want to remove more previous routes like https://docs.flutter.io/flutter/widgets/Navigator/pushNamedAndRemoveUntil.html but your question doesn't contain any information that would allow do diagnose your problem. – Günter Zöchbauer Oct 07 '18 at 13:50
  • Yes. Just found out now. Thanks though. – Kingsley CA Oct 07 '18 at 13:54

6 Answers6

82

I figured it out. It was the Navigator.pushAndRemoveUntil function. Where i had to pass the PaymentSuccessful widget as the newRoute, and the "/Home" route as the predicate

  _navPaymentSuccessful(){
    Navigator.pushAndRemoveUntil(
      context, 
      MaterialPageRoute(
        builder: (context) => PaymentSuccessful()
      ), 
     ModalRoute.withName("/Home")
    );
  }
Kingsley CA
  • 10,685
  • 10
  • 26
  • 39
  • 18
    Can you please explain what's the purpose of using `ModalRoute.withName('/Home')` to complete your answer? – iDecode Jan 06 '21 at 15:55
  • @iDecode You can refer to the documentation here [https://api.flutter.dev/flutter/widgets/Navigator/pushNamedAndRemoveUntil.html] the ModalRoute.withName('/Home') is used to ensure that when the back button is pressed the user is navigated to the "/Home Screen" -> "To remove routes until a route with a certain name, use the RoutePredicate returned from ModalRoute.withName" – Chichebe Nov 22 '21 at 08:46
  • If you want to navigate to the `root` Screen, the replace `"/Home"` with `"/"`. And you can also provide route arguments to `MaterialPageRoute()` using his props `settings: RouteSettings(arguments: myArgs)` – Manu Nov 30 '21 at 13:02
  • to add more, here is the video explaining exactly this function: [Tutorial Link](https://www.youtube.com/watch?v=Ae7m9JHhi7Y&ab_channel=LearnwithShajeel) – Hardik Jan 19 '22 at 12:58
  • 1
    I found out that you don't need to specify the route with "/" but just write a predicate (_) => false. Here is my example: ```Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => LoginPage()), (_) => false);``` – konkri May 28 '23 at 14:37
42

Accepted Answer is correct. But you can try this too.

Navigator.pushAndRemoveUntil<dynamic>(
        context,
        MaterialPageRoute<dynamic>(
          builder: (BuildContext context) => YourPageNameGoesHere(),
        ),
        (route) => false,//if you want to disable back feature set to false
);
gsm
  • 2,348
  • 17
  • 16
17

even simpler and I think a better way would be to do it this way, this Schedules a callback for the end of the current persistent frame,to push to route /loginPage and removes all the previous routes,this way you can make sure that all the frames are rendered and then you navigate to next page.

 SchedulerBinding.instance.addPostFrameCallback((_) {
                Navigator.of(context).pushNamedAndRemoveUntil(
                    '/loginPage', (Route<dynamic> route) => false);
              });
Mahesh Jamdade
  • 17,235
  • 8
  • 110
  • 131
2

I would Suggest use WillPopScope in your Payment successful page and onWillPop method write following snippet of code:

 return WillPopScope(
      onWillPop: (){
        Navigator.of(context)
            .pushNamedAndRemoveUntil('/Home', (Route<dynamic> route) => false);
      },
      child: Scaffold()
};
dartKnightRises
  • 815
  • 15
  • 26
1

if you want to remove just single screen from stack, then you can do with this

Navigator.of(context).pushReplacementNamed(
                  RouteHelper.navbar, //this is our other route name
                  arguments: {code}, // this is the argument which we are sending to second screen
                );

Hope, it would be helpful for someone.

Aqeel Mughal
  • 2,105
  • 2
  • 6
  • 14
0

Try this if you want pass arguments to new page:

Navigator.of(context).pushNamedAndRemoveUntil(
      '/new-route-name',
      arguments: {
         any object
      },
      ModalRoute.withName("/the-route-name-that-you-want-back-to-it")
);