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

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

Related

Pop screen in GetX

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.

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";
}

Flutter dont close bottomSheet on BottomNavigationBar tap

I have a problem with a BottomNavigationBar. My app has two screens and one of them has a bottom sheet that doesn't hide on disposing of the first screen when I'm tapping on the icon of the second screen. BottomNavigationBar works normally and screens switch, but how to hide the bottom sheet of the first screen when shown the second screen I have no ideas. Could you help me solve that?
Calling:
void _showForm(int id) async {
showBottomSheet(
context: context,
elevation: 5,
builder: (context) => BottomSheetSwitch(_refreshJournals, id));
}
Closing (inside bottom sheet):
Navigator.of(context).pop();
P.S. I couldn't solve that problem, so I change showBottomSheet to showModalBottomSheet like that was in: how to set showModalBottomSheet to full height?
You can try to provide a key to the stateful widget of BottomSheet. And access that key's context just use the Navigator's pop method on tap or change of the screen. It might help you.
You can use it like
Navigator.of(key.currentContext).pop();
Else call the function of your BottomSheet using the key. Like as below
Declare GlobalKey with state in your currentWidget.
GloabalKey<BottomSheetWidgetState> closeKey = GloabalKey();
Declare one function closeBottomSheet in your bottomsheet widget state.
void closeBottomSheet(){ Navigator.of(conext).pop(); }
Call the function using the key.
closeKey.currentState.closeBottomSheet();
And done.

How to launch a another screen with different functions based on the user onTap

I am currently working on a Math app that has a category screen which has Cards for different math operations(plus, Minus, Division). when user taps on it displays the next screen with questions and answers. I had create a separate class for question and answer generation and inside it I had created methods for each math operation like below
class QandAgeneration{
//Perform the addition quiz generation
Map addition(){}
//Perform the subtraction quiz generation
Map subtraction(){}
//Perform the division quiz generation
Map division(){}
// Generate answers
List generateAnswers(){}
}
In the next screen I want to display the output of the user selected operation eg:- QandAgeneration.addition() as widgets and those widgets state changed to display the next question when user press a button to select the answer. I think I can do it by using if else by passing the String value from category screen to next screen by using constructor with string parameter. Then I can do it as below
if(widget.selectedType == 'addition'){
QandAgeneration.addition()
}
else if(widget.selectedType == 'subtraction'){
QandAgeneration.subtraction()
}else{
QandAgeneration.division()
}
Is this is the best way to achieve this function. Is there any other method?
Create a class for another screen and pass to this screen needed parameters. On another screen implement functionality based on passed data. For example:
class AnotherScreen extends StatelessWidget {
final data;
AnotherScreen(this.data);
#override
void build(BuildContext context) {
if (data == 'firstType') {
return widgetForDataWithFirstType(data);
}
return widgetForDatawithSecondType(data);
}
}
And move to this screen:
Navigator.push(
context,
MaterialPageRoute(builder: (context) => AnotherScreen(data)),
);
Where data - parameter that you need to receive to another screen.
You can read more about how to work with navigation in Official Documentation.

How to update a CustomScrollView when returning from detail screen

I have a Scaffold that contains a CustomScrollView showing a list of items that the User has not tried (and another one that shows the items the User has tried).
Using the fantastic package flutter_sticky_header, I populate the CustomScrollView with a variety of SliverStickyHeaders and SliverLists to get something along the lines of:
Fruits
Apples >
Bananas >
Pears >
Vegetables
Broccoli >
Cabbage >
Potatoes >
The SliverLists are made up of some GestureDetector 'buttons' that take the user to a DetailScreen when tapped using something like:
onTap: () async {
bool result = await Navigator.push( *go to the DetailScreen* )
setState(() {
if (result) { *change the icon on the button* }
}
}
On the DetailScreen the User can indicate whether or not they have tried the item and when they Pop back to the first screen and the CustomScrollView, an icon on the button they pushed is updated to show a checkmark for items tried and a '>' for those they haven't.
Unfortunately, when the User Pops back to the list of items 'not tried', the item they just indicated having 'tried' is still there, and remains until the User navigates away and back.
What I want to do is update/refresh/rebuild the entire list so that when the User Pops back after changing an item from 'not tried' to 'tried' that item is no longer in the list of not tried items (and vice versa).
Basically, when the User Pops back, I can update the state of the specific widget that took them to the DetailScreen, but can't figure out how to update/refresh the state of the parent CustomScrollView widget up the chain.