Pop screen in GetX - flutter

I have a list screen like below
I would like click back in screen 5 and pop to screen 2 ,
When click back screen 2 -> pop to screen 1
Can you help me check it. Thanks
I use GetX.
and push screen 1 -> 5
Future<dynamic> goToScreen(Widget screen,
{dynamic arguments, bool preventDuplicates = true}) async {
int? id = Get.find<MainController>().currentScreenModel.navKey;
if (arguments != null) {
DataHolder().args = arguments;
}
return Get.to(() => screen,
id: id, arguments: arguments, preventDuplicates: preventDuplicates);
}

If the times you want to go back are fixed, in your case, 3 times, you can just use Get.close(3), this will pop the screen 3 times.
But, if you're not sure if in the future this could change, you can also use the route name (which is harder to get since you're using unnamed routes) Get.until((route) => Get.currentRoute == yourRouteName);.
When you use Get.to, GetX is going to print your route name in the console, you can copy the screen 2 route's name and then use that with Get.until.

Related

Pop a screen in between in Flutter

I pushed three screens: ScreenOne > ScreenTwo(1) > ScreenTwo(2)
I'm at the second instance of ScreenTwo now, but I want to remove the first instance of ScreenTwo from the stack, so it should be ScreenOne > ScreenTwo(2).
When launching ScreenTwo(2) I know I shouldn't remove ScreenTwo(1) from the stack yet, so I can't just call Navigator.replace(). I really need to have ScreenOne > ScreenTwo(1) > ScreenTwo(2) for some time, and then remove the first instance of ScreenTwo(1).
How I can handle it? Navigator.pop() and similars only take into account the screen or screens on top of the stack.
If someone needs more context, this is for a phone app. Not an app for phones, but an app that mimics the behavior of a phone. So in reality, we have HomeScreen > CallScreen(Caller1) > CallScreen(Caller2). As the app can handle different calls at a time the first approach has been to map every call to a CallScreen and let every screen handle their own call events, so the first call can finish while the user is talking in the second one.
As discussed in this post:
How can I pop to specific screen in flutter
I quote:
If you didn't define any route in the MaterialApp then you need to define at the time of push.
Navigator.of(context).push(
MaterialPageRoute(builder: (_) {
return SecondPage();
},
settings: RouteSettings(name: 'SecondPage',),
));
You need to define the same route name
Navigator.of(context).popUntil((route){
return route.settings.name == 'SecondPage';
})
;
Or as an alternative if you did define the routes you can use that:
pushNamedAndRemoveUntil(
'/BottomNavigation', (Route<dynamic> route) => false);
In this case it is most suitable that you go from screen1 > Screen2 > replace previous with Screen3
Use this navigation from screen 2 to screen 3.
Navigator.pushReplacementNamed(context,"Third Screen");

Flutter, how to update reactive list declared in first screen controller from the second screen?

I am using GetX in my project. Lets suppose I have two screens. Each screen have a button.
The controller of first screen have observable list of objects. When a button in first screen is pressed, one of the object list is sent to second screen.
In second screen user changes the value of the data received and when save button is pressed, I want to update the observable list in first screen as well.
I know I can use Get.back() to send updated data back to first screen. I could do following in second screen
Get.back(result: [
{"updatedObject": listDetails}
]);
And in first screen I could do
Get.to(() => SecondScreen(), arguments: [
{"list": listDetails[index]}
]).then((result) {
// result[0]["updatedObject"] // use this to update list observable
});
My Question.
Can I update list in first screen without navigating back to first screen when Save button is pressed.
I am pretty new with GetX and i am trying to learn it. Thanks
As long that when you navigate to the second screen using Get.to() then you can always access the data in the controller of the first screen using Get.find().
Here's a sample I tweaked it a little bit:
Get.to(() => SecondScreen(), arguments:
{"index": index},
)
On the controller on the second screen you can access(view/update) the data using the index.
#override
void onInit() {
index = Get.arguments['index'];
// View
name = Get.find<FirstScreenController>().listDetails[index].name;
print(name);
// Update
Get.find<FirstScreenController>().listDetails[index].name = "John";
}

How to execute function on Navigator pop from a nested stateless widget

I have an UI like the image. The listView is generate from data coming from FutureBuilder -> future.
Each item in the list is a ListTile and the red marked part is another stateless widget that navigates to another page do do some update operation.
I am going from one screen to another using Navigator.of(context).pushNamed(screenName).
If I want to do some operation when then Navigator.of(context).pop() then I can use
Navigator.of(context).pushNamed(AddFamilyMember.routeName).then((value) => {})
But I can not perform it from a list item in the list
So how to do it?
The code would be too complicated that is why I am drawing this image
So according to the image when I come back from screen 4 to screen 2 I can call Navigator.of(context).pushNamed(AddFamilyMember.routeName).then((value) => {})
I want to do the same when I come back from screen 6 to screen 2
Please note image 3 is not a screen . this widget represent one list item from the list view
Marked 7 is the widget that takes to screen 6
So how to do it?
what you can do here when you naviagte to other screen make your navigation as async and save the vale in variable the based on this variable you can perform a funtion .....
onTap: () async {
var result = await Navigator.of(context).pushNamed(
Routes.inviteFamilyMember,
arguments: {'data': null});
if (result == "Update") {
_refreshIndicatorKey.currentState.show();
}
}
on poping back retun value true or false based on this value trigger the refresh indicator still have doubts let me know

Flutter : How to refresh screen when user come back to it from any other screen

For ex.
I am on Screen-1 , push screen and goto Screen-2.
and then I replace Screen-2 with Screen-3
and now I pop that Screen-3 with pass some data
and come back to Screen-1
and I want refresh data in Screen-1
You can use something like this (but you must go from 3 to 2 and finally 1) to get some value then refresh it:
var result = await Navigator.of(context).push(
MaterialPageRoute(builder: (context) => Screen2()));
if (result != null) {
setState(() {
valueYouChangeIt = result;
});
}
And then send this value back from Screen2 with:
_sendDataBack(BuildContext context) {
Navigator.pop(context, valueToSendBack);
}
Or if you want to refresh everything you can write _initState function where you initialize your data and then call _initState on result.
Said that, all this can be super tedious process, so if it's a small app with 2 to 5 screens it can be ok, but with more screens, like someone else commented, I'd prefer to use Provider.

How to pop two screens without using named routing?

For example, my current routing is like this:
Login -> Screen1 -> Screen2 -> Screen3 -> Screen4
I'd like to go back to Screen2 from Screen4.
I can't use named routing, because I have to pass a parameter to Screen2.
Push Screen2 in Screen4 is not a good solution.
Use popUntil method of Navigator class.
e.g.
int count = 0;
Navigator.of(context).popUntil((_) => count++ >= 2);
However, I would recommend defining names for your routes and using popUntil as it is designed as per docs.
You can just pop it two times;
nav = Navigator.of(context);
nav.pop();
nav.pop();
The class from which the transition will be made as StatefulWidget. To press action add the pushNamed navigator with then, which will trigger after returning to this screen. Pass setState to update the widget:
onTap: () {
Navigator.pushNamed(
context,
RouteNames.viewExercises,
).then((value) {
setState(() {});
});
},
Screen from which to return to be used:
Navigator.of(context)
..pop()
..pop()
..pop();
where ..pop() is used as many times as needed to back.
if you would like to pop until three times, You can use the code in below.
int count = 3;
Navigator.of(context).popUntil((_) => count-- <= 0);