How to use popUntil properly to reach the root of the stack?

I have pushed to two screen and wish to go back to my main home page. I tried doing that by using popUntil however it is not giving me the req result and just showing a black screen. Do i need to set a new route to my main page , even though i don't want to create a new instance of it ?

My code:

class Completed extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

  return MaterialApp(
      title: 'Completed Screen',
      home: CompleteScreen(),
      routes: <String, WidgetBuilder>{
       // "/my-app": (BuildContext context) => MyApp()
      }
 );
}
}

class CompleteScreen extends StatelessWidget{
  @override
  Widget build(BuildContext context){

    Container Complete = Container(
        child: Column(
           .....
                  FlatButton(
                    onPressed: (){        
                      Navigator.popUntil(
                        context,
                        ModalRoute.withName('/'),
                      ); 
                      // Navigator.popUntil(context, ModalRoute.withName(Navigator.defaultRouteName));
                    },              
                ),

          ],
        ));

    return Scaffold(
        body:  Complete
    );
  }
}


My main page



void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My App',
      home: DefaultTabController(length: 2,child: MyHomePage(title: '')),
      routes: <String, WidgetBuilder>{
       "/TaskScreen": (BuildContext context) => new task(),
      }
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

 @override
  Widget build(BuildContext context){

   final list =  ListView.builder(
     itemBuilder: (context, position) {
       return Ink(
         child: InkWell(
           onTap: (){
             Navigator.of(context).pushNamed("/TaskScreen");
           },
           child: Card(
             ...
           ),),); },);

   return Scaffold(
   ...
 }
}

I tried using '/TaskScreen' and '/my-app' however even that didn't work.

2 answers

  • answered 2019-05-21 12:59 danypata

    The route in the popUntil has a property called isFirst that returns true if the route is the first route in the navigator. So in your case, you can use something like:

    Navigator.of(context).popUntil((route) {
          return route.isFirst;
        });
    

  • answered 2019-05-21 13:01 Escobar

    You could try this

    Navigator.popUntil(
          context,
          ModalRoute.withName(
            Navigator.defaultRouteName,
          ),
        ),
    

    As defaultRouteName works as the first screen opened when the app starts.

    EDIT

    So, as mentioned below, named routes won't work with Navigator.defaultRouteNamenor route.isFirst, the best approach to solve this I've found is declaring all your routes in the main page, as these will become global (or that's what I understood), so your code would end something like this

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'My App',
          home: DefaultTabController(length: 2,child: MyHomePage(title: '')),
          routes: <String, WidgetBuilder>{
            "/": (BuildContext context) => MyApp(), (or MyHomePage())
            "/TaskScreen": (BuildContext context) => new task(),
          }
        );
      }
    }
    

    With that done, anytime you want to go back to the main page you just have to call

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

    Hope that works for you.