Reputation: 3225
I'm implementing an authentication flow in my Flutter app.
After a sign in attempt, the CheckAuth (which checks whether a user is signed in or not and then opens home screen or sign up screen accordingly) is opened with this code:
void _signIn() async {
await _auth
.signInWithEmailAndPassword(
email: _userEmail.trim(), password: _userPassword.trim())
.then((task) {
// go to home screen
if (task.getIdToken() != null) {
setState(() {
Navigator.pushReplacement(
context,
new MaterialPageRoute(
builder: (BuildContext context) => new CheckAuth()));
});
} else {
print("Authentication failed");
}
});
}
Problem: I can successfully sign in to the app, but if I tap back button after I sign in, it goes back to the sign in screen (while I expect it to exit from the app).
Question: How to move from one screen to another in Flutter without the way back?
Do I need to somehow delete the navigator history? Or don't use navigator at all? I tried Navigator.replace method, but it didn't seem to work.
Upvotes: 132
Views: 140888
Reputation: 2469
It was not working for me because I was using the home proptery rather than initialRoute on the MaterialApp.
This is a link where there's the folloing warning which helped me to spot the error: https://docs.flutter.dev/cookbook/navigation/named-routes#2-define-the-routes
Warning: When using initialRoute, don’t define a home property.
Upvotes: 0
Reputation: 406
Here is the solution -
Use pushAndRemoveUntil instead of pushReplacement
Also, can be use maintainState: true
For set root page
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (context) => pageName, maintainState: true),
(Route<dynamic> route) => false);
For Push Page one page to another
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => pageName,
maintainState: false),)
**If you want to refresh always while appearing page then use: **
maintainState: false
Upvotes: 5
Reputation: 387
Navigator.of(context, rootNavigator: true).pop();
Navigator.pushNamed(context, '/');
Upvotes: 0
Reputation: 23
For anyone wondering there is a new argument that needs to be returned false Navigator.of(context).pushNamedAndRemoveUntil('/', (route) => false);
Upvotes: 2
Reputation: 615
if you are working with Getx state managemaent then you can try this
Get.of(()=> NewPage());
Upvotes: -2
Reputation: 221
Just simply add the below code:
Navigator.of(context).pushNamedAndRemoveUntil('/routeName', (route) => false);
Upvotes: 6
Reputation: 543
I have resolved this by popping from current page and showing new page:
Navigator.pop(context);
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context) => newPage));
Upvotes: 5
Reputation: 161
I think you probably have already solved this. But you can set "automaticallyLeadingImplied: false" in the AppBar of the Scaffold you are navigating to.
Upvotes: 5
Reputation: 34270
We can use routes for the same Like:
routes: {
LoginScreen.route_name: (_) => LoginScreen(),
.....
},
And use below code whenever you want to push and remove the backstack
Navigator.of(context).pushReplacementNamed(LoginScreen.route_name);
Note: Define static String inside widget LoginScreen
Upvotes: 3
Reputation: 18177
You can use the pushAndRemoveUntil
method:
Push the given route onto the navigator that most tightly encloses the given context, and then remove all the previous routes until the
predicate
returns true. To remove all the routes below the pushed route, use a [RoutePredicate] that always returns false (e.g.(Route<dynamic> route) => false
).
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => MainPage()),
(Route<dynamic> route) => false,
);
Upvotes: 110
Reputation: 3384
You need to use
Navigator
.of(_context)
.pushReplacement(new MaterialPageRoute(builder: (BuildContext context) => page));
Where _context
is object of BuildContext
And page
is which page you directed to.
Upvotes: 19
Reputation: 277617
You need to use Navigator.pushReplacement
when leaving the auth screen too. Not just when redirecting to login page.
Upvotes: 211