In Flutter Which method gets called when pop back to Screen A from Screen B - flutter

I have updated my Sqlite Table in Screen B and want to reflect that change in Screen A Also.
So when Pop back from Screen B> Screen A nothing updated.
In Android, we have onResume() to make changes reflect in Activity A.
I have used Widgets Binding Observer but it works if app background, foreground.
Navigator.of(context).pop();

You can await Navigator.push, when pop is called anything below Navigator.push will be called. Ex:
await Navigator.push(SomePage());
/// This will be called after SomePage cals Navigator.pop();
doSomething();

You can get back from the second page with data like this:
// Second Page
Navigator.pop(context, 'result');
Then by the below code on the first page, you are able to lunch the second page and wait until return from it and get data.
// First Page
var result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
);

Related

Flutter call setState after Get.back()

I need to reload page after Get.back(). How to do it? How to call any method on previous page as soon as possible after using Get.back()?
For example:
I'm on Page1
Go to Page2
Use Get.back(), so user back to Page1
Usually user now see Page1 exactly like when he leave Page1. How to reload now view Page1?
Maybe is any method to override what I can call every time after navigate one page back? This method must come from Page1, not from Page2
you can do await while navigating to page 2.
Example:
await Get.to(()=> Page2());
setState({
// perform update
});
the setState will get fired once you come back to page 1 from page 2
another, similar example, code from Page1:
ListTile(
title: const Text("Item"),
onTap: () async {
await Get.toNamed(page2);
setState(() {});
}),
Using this sample, refresh (setState) fired after return from Page2 to Page1.
on Page 2: You need to write this
Get.back(result: true);
on Page 1: wait for response
var response = await Get.to(()=> Page2());
if(response){setState({
// perform update
});}

Flutter get reference after navigation pop

I would like to get a reference to the screen I am going to show.
With this code:
Navigator.of(context).pop()
I actually going back to the previous screen but I would like to access that reference to do some work.
How can I do that?
With my iOS background working in Swift I would have done something like that:
var newScreen = Navigator.of(context).pop();
You cannot create a reference because when you pop the current "route" all the data will be disposed.
But you can return a pop result to the awaiting parent as explained by official docs.
Something like:
//When you will dispose the pushed page/route you can pass your result to pop method
Navigator.pop(context, 'This is my new page result');
//In the parent page you will await for the result
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => MyPushedPage()),
);
print(result) //--> This is my new page result

How to call a function to update a value after popping a screen in Flutter?

Screen 1: shows list of item with add button.
Screen 2: form to add a new item to the list.
Screen 2 >> Screen 1 - While calling navigator.pop() in screen 2, how to call method/setState (to update list) in screen 1?
Can anyone help me out?
I don't want to relaunch screen again. I just need to run a method to update my list after popping previous screen?
When you navigate from Screen 1 to Screen 2, you use the push method. The push method returns a Future object.
You can use the then method of Future to execute your code after Screen 2 was popped from the navigation stack.
Navigator.of(context)
.push(MaterialPageRoute(
builder: (context) => Screen2(),
))
.then((value) {
// you can do what you need here
// setState etc.
});
You can use Provider or BLoc or you can await for the result when you push the page
You can do it like this :
// this method waits for the pop to be called
var data = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => LoginScreen()),
);
debugPrint(data);
// here the second argument is the data
Navigator.pop(context, "data"); // popped from LoginScreen().
output
data
Same method can also be done like below
// this method waits for the pop to be called
Navigator.push(
context,
MaterialPageRoute(builder: (context) => LoginScreen()),
).then((data){
// then will return value when the loginScreen's pop is called.
debugPrint(data);
});
Here is a good article to look into this
https://medium.com/flutter-community/flutter-push-pop-push-1bb718b13c31
Navigator.pop has a second argument called result.
You could then return the value that you need to the first page that will read it as the return value of Navigator.push

Flutter - set result to return when the user navigates back

When calling Navigator.pop() a result can be passed to the previous screen. Is there a way to set the result so that if the user navigates back on their own the result is still returned to the previous page?
I could pass an object to the second page and then modify it so that the first page can check it when the second page returns, but I'd rather use the result returned from the Navigator as it's more readable.
Overriding the back button's tap detector as I've seen suggested elsewhere is not an acceptable solution because the user may navigate back in some other way such as swiping or pressing the Android back button.
Yes, you can pass data between screens both ways.
While popping back, send the data you wish to send like this from the second screen
RaisedButton(
onPressed: () {
// The Nope button returns "data" as the result.
Navigator.pop(context, 'data');
},
child: Text('Nope!'),
);
And catch the result in the your first screen like this
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondScreen()),
);
source
For the other concern where the user is able to go back to the previous screen by pressing the back button, you can wrap your second screen with WillPopScope widget and provide the onWillPop callback. This will override the popping of the second screen and execute the callback where you can define the value you wish to return from the second screen.
#override
Widget build(BuildContext context) {
return WillPopScope(
child: Scaffold(), // or your widget
onWillPop: () {
return Future.delayed(Duration(microseconds: 0), () {
return Navigator.pop(context, "return-data");
});
},
);
}
Yes, this is possible, when navigating to Screen B from Screen A, make the onTap() functionasynchronous and await the result from Screen B.
Check the code below: It works perfectly:
On Screen A, put this code:
onTap: () async {
// receive the data you are sending from screen B here
final result = await Navigator.push( context);
},
On Screen B, put this code:
onTap: (){
// pass the data you want to use in screen A as the second paramter
Navigator.pop(context,number);
},
I hope this helps

How to refresh a page after back button pressed

I have a "list page". and an add page. User clicks "add page", goes to a new page where they add some entity. Then I pop the Navigator, and user goes back to "list page".
At this point, I want to get notified somehow - callback maybe? override a method, I am not really sure - and re-read the information from database.
Is there a hook like this in Flutter? Or is there another pattern that I should use?
The Navigator.push method returns a future of the generic type of the Route:
Navigator.of(context)
.push(new MaterialPageRoute<String>(...))
.then((String value) {
print(value);
});
And inside the new route, when you have the value you need:
Navigator.of(context).pop('String');
If at your list page, you create function let say retrieveData() to read list of the data then call it inside initState, if you're using pushNamed route, the simple solution would be
Navigator.pushNamed(context, '/adddatapage').whenComplete(retrieveData());
If you're using push route,
Navigator.of(context).push(new MaterialPageRoute(builder: (context) => AddPage())).whenComplete(retrieveData);
That should be enough. No need to additional code on the add page. This will be works if user press back button also, again, without additional code in the add page.
Adding a option to #ian 's answer
Navigator.of(context)
.push(new MaterialPageRoute<String>(...))
.then((value) => setState(() => {}));
This worked for me. This will rebuild whenever page is loaded.
Write below code when redirect to screen 2,
Navigator.pushNamed(context, '/screen2').then((_) {
// This block runs when you have returned back from screen 2.
setState(() {
// code here to refresh data
});
});
Use
Navigator.pop(context);
in screen 2 to back to screen 1
i use Navigator.pushAndRemoveUntil, it will refresh the page and load the data again, this is example :
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (context) =>
CustomerMainPage()),
(Route<dynamic> route) =>
false);
I passed a callback method into the "add" page as a Navigator route argument. The callback is a method in my list page. The "add" page executes the callback when exiting. The callback method then simply refreshes the data and calls setState to refresh the screen.
My architecture is using Provider and viewmodels, but it should be straight-forward in a standard app as well.
For named route:
Navigator.pushNamed(context, '/page2').then((_) {
// This block runs when you have returned back to the 1st Page from 2nd.
setState(() {
// Call setState to refresh the page.
});
});
For unnamed route:
Navigator.push(context, MaterialPageRoute(builder: (_) => Page2())).then((_) {
// This block runs when you have come back to the 1st Page from 2nd.
setState(() {
// Call setState to refresh the page.
});
});