I try to build a flutter app and want to navigate trough the pages.
I build a drawer with a menu with several items to open new pages - that works fine.
onTap: () {
Navigator.of(context).pop();
Navigator.push(
context,
new MaterialPageRoute(
builder: (BuildContext context) => new Page1(),
),
);
},
By pressing on the Page1 menuitem page1 opens fine.
Inside page1 I have a slidable list with "edit" and "details". I open this with
onTap: () {
Navigator.of(context).pop();
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => new DetailsPage(),
),
);
},
In the details Page I see all the things i wanna see, but when I press the Back button in the appBar i am back at home screen with closed drawer.
I tried to put onPressed: () => Navigator.pop(context); inside the appBar section but this doesn´t work either.
Now I got what I want by using always Navigator.push but I am sure that this is not right, so that navigator stack gets bigger and bigger.
What I do wrong? Why .pop does not bring me to the last page?
Any ideas?
Thx in advance
Patrick
Just remove the line with the Navigator.of(context).pop();in the Page1 onTap.
you can use pushReplacement in any cases you need to remove current page from stack and route to new page.
Replace the current route of the navigator that most tightly encloses
the given context by pushing the given route and then disposing the
previous route once the new route has finished animating in.
here is the documentation
Related
I have three screens: 1, 2, and 3.
I want to switch from screen 2 to screen 3, but when I pop screen 2 and push screen 3, then it shows screen 1 for a while, then it shows screen 3, so is there any way to switch screens using pop after push or not?
this code not expectations
Navigator.push(
context,
MaterialPageRoute<Widget>(
builder: (context) => widget,
),
);
Navigator.pop(context);
Using pushReplacement insted of push
Navigator.pushReplacement(
context,
MaterialPageRoute<Widget>(
builder: (context) => widget,
),
);
Using pushReplacement insted of push
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => widget,
),
);
The behavior you're describing is likely because when you call Navigator.pop(context), it removes the current screen (screen 2) from the navigation stack, but the framework hasn't yet had a chance to build and display the new screen (screen 3) that you pushed. So, for a brief moment, the previous screen (screen 1) is visible.
One way to switch screens without that flicker is to use Navigator.pushReplacement instead of Navigator.push followed by Navigator.pop. Navigator.pushReplacement removes the current screen from the navigation stack and replaces it with the new screen, all in one step.
Example:
Navigator.pushReplacement(
context,
MaterialPageRoute<Widget>(
builder: (context) => widget3,
),
);
This will directly switch from screen 2 to screen 3.
It is generally not recommended to use both Navigator.push() and Navigator.pop() together in the same function call, as this can cause unexpected behavior. Instead, you can use Navigator.replace() to replace the current screen with a new one, or use Navigator.pushNamedAndRemoveUntil() to push a new screen and remove all the screens that come before it.
I am fairly new to state management in Flutter, and I have an application where the user will be interacting with dialogs, and a dialog may have a button to open another dialog which can result in the following:
https://i.stack.imgur.com/VBSzr.png
As shown, multiple issues arise when more than one is opened at once -- most notably the previous dialog is still visible in the background. So when a user opens a new dialog, is there any method where I can hide the dialog behind it, and when the frontmost dialog closes, show the previous one which is hidden? Thanks in advance.
Use Navigator.pop(context); method to close the dialog on your button's onPressed before opening the second dialog.
And then while closing your second dialog you can reopen your previous dialog.
Example:
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text("Hello World"),
content: Text("This is content"),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context); //Close your current dialog
//TODO:open your second dialog
},
child: Text("Open"))
],
);
});
I would first try to re-think the logic for opening multiple dialogs at the same time.
Maybe there is a quick workaround for that, but if you keep adding more and more dialogs, then it would become a mess.
Since showDialog<T> function returns Future<T?>, you could potentially use await and wait until the first dialog is closed and then open the second one and so on:
bool canContinue = await showDialog<bool>(
context: context,
builder: (context) => YourWidget(),
);
Alternatively, you could pop by using Navigator but as said, this will be visible to the user that something weird is going on (pushing and popping dialogs programatically).
When I press the device back button, it navigate to the homepage but not to the previous page.
I would like to know how to navigate to the previous page using the the device back button.
Thank you
You might have used Navigator.pushReplacement which destroys the previous page and creates the new page.However if you use Navigator.push pressing the back button will navigate you to the previous screen.
Example:
Container(
child: Center(
child: TextButton(child: Text("Next page"),onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context) => Page2(),)); // back button will navigate to previous screen
//Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => Page2(),)); // back button will not navigate to previous page
},),),),
It was a Materialapp widget problem.
I solved the problem by deleting the Materialapp widget that was in one of the pages.
This occurs because the previous navigation was not saved in the route stack.
What you should do is this:
Widget A
Navigator.push(context, WidgetB());
Inside Widget B, press the device button and you will return to widget A.
It is important that in widget A you are not using replacement or another that removes widget A from the stack.
You can use:
Navigator.pop(context);
or
Navigator.pushNamed(context, '/routeName');
i have app with two screens,one fingerprint screen and another home screen.once
fingerprint is authenticated i will get routed to home screen(using navigator.push()),but if I click back button in phone now it is getting routed to fingerprint screen again.Now how to close the app instead of routing back to finger print screen?
Use Navigator.pushReplacement. It will replace the current topmost widget on the stack with the new one instead of simply pushing it on top.
Example usage -
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (BuildContext context) => MyHomePage()));
More documentation about this method can be found here.
put your homepage scaffold inside WillPopScope as a child
WillPopScope(
child: Scaffold(...),
onWillPop: () async {
return false;
},
),
I want my flutter app to navigate from my last screen back to the home page. Currently, it navigates back to the previous page which I do not want.
onPressed: () {
Navigator.pop(context, MaterialPageRoute(builder: (context) => MyHomePage()));
},
I expect the button to return me back to the Home Page
If you don't use named routes you can simply replace your code with this:
onPressed: () {
Navigator.of(context).popUntil((route) => route.isFirst);
},
This will pop the navigation stack until it reaches the first item which might be your home page.
Can't you just use Navigator.pushAndReplace(MaterialPageRoute(builder: (context) => MyHomePage())); for navigation back to the home page?