Reputation: 63
I am making an application, In my sign out dialog, i got this code.
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) {
return AuthScreen();
}), (route) {
// if( route is (MaterialPageRoute('/')))
// {
// }
// print(route);
return false;
});
I just want to push AuthScreen and remove until the route screen. How to do that?
So after this code, stack contains root screen, and AuthScreen.
Upvotes: 2
Views: 18672
Reputation: 777
Writing this answer considering other cases people might have and looking for a solution.
If you've implemented your own custom PageRoute/PageRoutBuilder and using this everywhere to push and pop pages, the suggested answer might not work. At least, that was it in my case.
One way to overcome this problem would be, by using named routes like everybody (and the doc itself) suggests. But regardless of the “Why”, if you don't want to go in that way, I came here to propose a new solution.
HomePageView
). Later, when you wish to pushAndRemoveUntil until, write the second argument like below:Navigator.of(context).pushAndRemoveUntil( MyCustomPageBuilder(MyStatelessView()), (Route<dynamic> route) { if (route is MyCustomPageBuilder && route.instanceVariable == 'HomePageView') { return true; } return false; } );
Navigator.of(context).push(MyCustomPageBuilder<HomePageView>)
and then, while pushing your MyStatelessView
and popping the previous pages until HomePageView
, you could write:
Navigator.of(context).pushAndRemoveUntil( MyCustomPageBuilder<MyStatelessView>(MyStatelessView()), (Route<dynamic> route) { if (route is MyCustomPageBuilder<HomePageView>) { return true; } return false; } );
They both will work. But I suggest you to go with second one.
Upvotes: 2
Reputation: 3326
You can do this:
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (BuildContext context) => AuthScreen()),
ModalRoute.withName('/') // Replace this with your root screen's route name (usually '/')
);
Another way you can try is:
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (BuildContext context) => AuthScreen()),
(Route<dynamic> route) => route is RootPage (your root page's type)
);
Yet another one:
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (BuildContext context) => AuthScreen()),
(Route<dynamic> route) => route.isFirst (pop until your first page)
);
Sample app:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:in_app_update/in_app_update.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => MyHome(),
},
);
}
}
class MyHome extends StatelessWidget {
const MyHome({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Sample App'),
),
body: Center(
child: TextButton(
onPressed: () => Navigator.push(
context, MaterialPageRoute(builder: (context) => MyChild())),
child: Text('To child page'),
),
),
);
}
}
class MyChild extends StatelessWidget {
const MyChild({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('My Child'),
),
body: Center(
child: TextButton(
onPressed: () => Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (BuildContext context) => MySecondChild()),
ModalRoute.withName('/')),
child: Text('Push to Second Child and remove until homepage'),
),
),
);
}
}
class MySecondChild extends StatelessWidget {
const MySecondChild({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('My Second Child'),
),
body: Center(
child: TextButton(
onPressed: () => Navigator.pop(context),
child: Text('Pop'),
),
),
);
}
}
Upvotes: 12