Flutter remove all routes
DartFlutterDart Problem Overview
I want to develop a logout button that will send me to the log in route and remove all other routes from the Navigator
. The documentation doesn't seem to explain how to make a RoutePredicate
or have any sort of removeAll function.
Dart Solutions
Solution 1 - Dart
I was able to accomplish this with the following code:
Navigator.of(context)
.pushNamedAndRemoveUntil('/login', (Route<dynamic> route) => false);
The secret here is using a RoutePredicate that always returns false (Route<dynamic> route) => false
. In this situation it removes all of the routes except for the new /login
route I pushed.
Solution 2 - Dart
i can done with the following code snippet :
Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) =>
LoginScreen()), (Route<dynamic> route) => false);
if you want to remove all the route below the pushed route, RoutePredicate always return false, e.g (Route
Solution 3 - Dart
Another alternative is popUntil()
Navigator.of(context).popUntil(ModalRoute.withName('/root'));
This will pop all routes off until you are back at the named route.
Solution 4 - Dart
Another solution is to use pushAndRemoveUntil()
. To remove all other routes use ModalRoute.withName('/')
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (BuildContext context) => Login()),
ModalRoute.withName('/')
);
Reference: https://api.flutter.dev/flutter/widgets/NavigatorState/pushAndRemoveUntil.html
Solution 5 - Dart
In case you want to go back to the particular screen and you don't use named router can use the next approach
Example:
Navigator.pushAndRemoveUntil(context,
MaterialPageRoute(builder: (BuildContext context) => SingleShowPage()),
(Route<dynamic> route) => route is HomePage
);
With route is HomePage you check the name of your widget.
Solution 6 - Dart
If you are using namedRoutes, you can do this by simply :
Navigator.pushNamedAndRemoveUntil(context, "/login", (Route<dynamic> route) => false);
Where "/login" is the route you want to push on the route stack.
Note That : > This statement removes all the routes in the stack and makes the pushed one the root.
Solution 7 - Dart
I don't know why no one mentioned the solution using SchedularBindingInstance, A little late to the party though, I think this would be the right way to do it originally answered here
SchedulerBinding.instance.addPostFrameCallback((_) async {
Navigator.of(context).pushNamedAndRemoveUntil(
'/login',
(Route<dynamic> route) => false);
});
The above code removes all the routes and naviagtes to '/login' this also make sures that all the frames are rendered before navigating to new route by scheduling a callback
Solution 8 - Dart
Not sure if I'm doing this right
but this suits my use-case of popping until by root widget
void popUntilRoot({Object result}) {
if (Navigator.of(context).canPop()) {
pop();
popUntilRoot();
}
}
Solution 9 - Dart
In my case this solution works:
Navigator.pushNamedAndRemoveUntil(" The Route you want to go to " , (Route route) => false);
Solution 10 - Dart
This is working for me. Actually, I was working with bloc but my issue was login screen bloc. It was not updating after logout. It was holding the previous model data. Even, I entered the wrong entry It was going to Home Screen.
Step 1:
Navigator.of(context).pushNamedAndRemoveUntil(
UIData.initialRoute, (Route<dynamic> route) => false);
where,
UIData.initialRoute = "/" or "/login"
Step 2:
It's working to refresh the screen. If you are working with Bloc then It will very helpful.
runApp(MyApp());
where,
MyApp() is the root class.
Root class (i.e. MyApp) code
class MyApp extends StatelessWidget {
final materialApp = Provider(
child: MaterialApp(
title: UIData.appName,
theme: ThemeData(accentColor: UIColor().getAppbarColor(),
fontFamily: UIData.quickFont,
),
debugShowCheckedModeBanner: false,
//home: SplashScreen(),
initialRoute: UIData.initialRoute,
routes: {
UIData.initialRoute: (context) => SplashScreen(),
UIData.loginRoute: (context) => LoginScreen(),
UIData.homeRoute: (context) => HomeScreen(),
},
onUnknownRoute: (RouteSettings rs) => new MaterialPageRoute(
builder: (context) => new NotFoundPage(
appTitle: UIData.coming_soon,
icon: FontAwesomeIcons.solidSmile,
title: UIData.coming_soon,
message: "Under Development",
iconColor: Colors.green,
)
)));
@override
Widget build(BuildContext context) {
return materialApp;
}
}
void main() => runApp(MyApp());
Here is My Logout method,
void logout() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
preferences.clear();
// TODO: we can use UIData.loginRoute instead of UIData.initialRoute
Navigator.of(context).pushNamedAndRemoveUntil(
UIData.initialRoute, (Route<dynamic> route) => false);
//TODO: It's working as refresh the screen
runApp(MyApp());
}
Solution 11 - Dart
First see chrislondon answer, and then know that you can also do this, if you do not have access to the (context).
navigatorKey.currentState.pushNamedAndRemoveUntil('/login', (Route<dynamic> route) => false);
Solution 12 - Dart
use popUntil like following
Navigator.popUntil(context, (route) => route.isFirst);
Solution 13 - Dart
In my case I had this painting Page 1 (Main) -> Page 2 -> Page 3 -> Page 4.
When I had to go to Page 4, the Page 2 and Page 3 going back did not have to appear, but I had to go to Page 1 again. At this point going to Page 4 I did:
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (BuildContext context) =>
Workout()),
(Route<dynamic> route) => route.isFirst);
The instructions are: go to page 4 (Workout) and remove all previous pages up to 1, that is (Main).
In your case that can be to switch from anything to a Login, then:
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (BuildContext context) =>
Login()),
(Route<dynamic> route) => false);
That is, go to Login and remove all previous pages, because there is a false.
Solution 14 - Dart
to clear route -
onTap: () {
//todo to clear route -
Navigator.of(context).pop();
Navigator.push(context, MaterialPageRoute(builder: (context) => UpdateEmployeeUpdateDateActivity(_token),));
widget.listener.onEmployeeDateClick(_day,_month, _year);
}