Flutter Navigator not working as expected - flutter

So I want a user to be able to go back to the '/' named route after he/she reaches upto a certain page. The condition is that when that page is reached, user should be routed to '/' only on Navigator.pop(context).
ie., Lets say I have routes configured such that :
User is at '/' > Clicks a button and pushNamed to '/abc' > Clicks a button and pushNamed to '/xyz' > Clicks a button and pushNamed to '/mnq'
Now, I want that when user is at /mnq and Navigator.pop(context) is executed, user should be sent back to '/' and not anywhere else.
When I'm at /xyz, I tried to do a Navigator.pushNamedAndRemoveUntil(context, '/mnq', ModalRoute.withName('/'), arguments:....) but It does not work because when Navigator.pop is executed after reaching /mnq, I see a black screen.
Is there a way to do this. Please note that I need to send arguments from /xyz to /mnq.

You can try use pushReplacementNamed()
'/' pushNamed to '/abc' pushReplacementNamed to '/xyz' pushReplacementNamed to '/mnq'
read this article for more information

pushNamedAndRemoveUntil is remove all page before. when you use back/pop, it will show black because no page before. you can pass argument with pushReplacementNamed Flutter - Pass values between routes using pushReplacementNamed or store data in local https://pub.dev/packages/shared_preferences

1st. on pressing a button to user should be sent back to '/'
simply use Navigator.popUntil(context, ModalRoute.withName('/'));
in place of Navigator.pop(context);
2nd. if user tab back button
WillPopScope(
onWillPop: () async {
Navigator.popUntil(context, ModalRoute.withName('/'));
return false;
},
child: Scaffold(......),
)

Related

How to update state when Navigating back to a page Flutter

i am creating a social media like app, when user clicks on post ,it redirects to a commentpage,in commentspage data is coming from a seperate API,so when go back using Navigator.pop(context), the data in home is not updated, if pressed like button,its not reflecting in ui, but updating in Api,
i wrapped Navigator with setstate but its not reflecting,
Use this on navigator push Navigator.push(context).then((value)=>setState((){}); when it pop the screen it will run the setState
Use this sentence to go to the second page so the function will wait second screen to close
bool result = await Navigator.push(context);
if(result){setState((){});}
when u close the second screen use this sentence Navigator.pop(context, true);
so when u comment has been posted successfully, u will back to screen one and complete the function if result boolean is true, else do nothing.

How to update screen or state on coming back to route using pop

I want to update a screen on coming back to that screen using Navigator.pop.
E.g. I have Home Screen and Some steps screens (Step1, Step2, Step3, Step4)
Home screen is a stateful widget and shows number of steps completed.
The flow is like
Home => Step1 => Step2 => Step3 => Step4
On any step, on pressing back or pressing close button, it should go back to Home screen and home screen should show updated state of steps completed. So i am navigating to next steps in steps screen using Navigator.popAndPushNamed so that Navigator.pop will go to Home screen.
And using Navigator.pushNamed(context, 'Step1').then in Home screen to update it.
But the problem is .then is called just on Step1 itself because it got popped and if user goes like
Home => Step1 => Step2 => Step3 => Home (using pop)
Home scren will only show Step1 is completed because when going from Step1 to Step2, its .then callback was called and when coming to Home from Step3 using Navigator.pop, no code is being executed and i am unable to update the Home Screen.
I know i can use Navigator.pushNamed(context, 'Home') from steps to go to home screen but it doesn't looks ok (it looks like Home screen was pushed on it instead animation should be like it goes back).
You can use a variable in your previous page which will keep a track, if you are coming from the next page and return a boolean true variable, stating that it has returned from the previous activity. You can use that varible in your init method and if the value of that variable is true you can just fire an event which will return appropriate state.
found the solution using RouteObserver and implemented something like example given in https://api.flutter.dev/flutter/widgets/RouteObserver-class.html
The method i was looking for didPopNext of RouteAware.
Check this, It's Working For Me!
Navigator.of(context).push(route).then((val){
//you can update you data here, when coming back
})

Flutter logout to remove all routes

Below is my app widget tree. If user is not logged in then login page is shown if user is logged in then work page. on account page I have logout button.Logout button implements push replacement and shows login page.
Issue is - When user click on back button again work page is shown.
How to remove all the routes from widget tree and only show login page after logout action?
Note - I am not using Named routes, just Push , Pop and Replacement
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.
Close your dialog by calling,
Navigator.pop(context);
and then call pushReplacement
void _doOpenPage() {
navigator.pushReplacement(
MaterialPageRoute(builder: (BuildContext context) => MyHomePage()));
}
pushReplacement Replace the current route of the navigator by pushing the given route and then disposing the previous route once the new route has finished animating in.
Read More here

Is there any way to pop several pages and reload the destination page?

I'm setting up an app which have to fill a long 4-part form, which might be displayed in 4 sequential screens in a mobile application. Now on the 4th part of the form, there is a submit button. User clicks on Submit and all the previous screens should be popped and user should be taken back to the Item-List screen(1st screen) where the updated data items must be shown. We won’t be pushing anything new here, just going back to a previous route. But the first page should be reloaded. How is this possible?
// Updated Answer
So if this is your first screen where you are pushing and where you want to call a function when poped, this is how you can do it.
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => RegisterScreen()))
.then((success) {
if(success){
// call your function here
}
});

How to refresh the page when user comes back to it from any other page using back key?

I have a page which is calling multiple classes and different widgets
and by clicking on it user can hop to any page.
Currently the issue is I want to refresh the original page everytime it is shown to user.
When it is freshly loaded (causing no issue for now).
When user comes back to it from some other page using back key.
old data is shown on the page, which I am trying to get rid of.
I have tried using Navigator.push method (Observer class method) and tried to listen when user presses backkey.
but there are multiple pages serving unique requests and I don't want to link everyone with that first page.
as while clicking Navigator.pop(context) method i'll have to pass some string.
Does any one know
how can I refresh the page when users comes back to it using backkey.
Navigator.push returns a Future when the MaterialPageRoute passed into it is resolved. You could await that Future to know when some other view has popped back to it.
Example,
Navigator.of(context).push(MaterialPageRoute(
builder:
(context) => NewView(),
),
).then((_) {
// Call setState() here or handle this appropriately
});
Had the same issue, the following worked for me (below code is in FirstPage()):
Navigator.push( context, MaterialPageRoute( builder: (context) => SecondPage()), ).then((value) => setState(() {}));
After you pop back from SecondPage() to FirstPage() the "then" statement will run and refresh the page.
NavigatorObserver can listen to route changes.
You need to create your implementation overriding didPop, didPush etc.
Then you can pass it to navigatorObservers field of MaterialApp or Navigator