Flutter: setState not updating UI after popping - flutter

I have a flutter application where the variable is initialized outside of the build function. In the build I have :
onPressed: (BuildContext context) async {
await showDialog(
context: context,
builder: (context) => Dialog(
...
Navigator.pop()
);
).then((_) => setState(() {
print("Test is this prints");
));
setState(){ flag = !flag }
}
The purpose of the setState is just so that the UI is updates after I close out of the dialog window. I have a util file that is makes some changes to the UI when I close out of the dialog, and I would like to see it reflected after I close out of the dialog.
For some reason, the UI is not changing even though setState should be rebuilding the widget since something changes.
When I do the .then(setState(){}), the console prints the print statement, but the UI is still not changing.

In which code or widget, you are using the flag variable.
If flag is not used in any of the widget then your UI will not be updated.

Remove multiple setState, just use one and also check usage of flag variable in your code.
.then((_) => setState(() {
flag = !flag
print("Test is this prints and updated flag value is $flag");
));

When rebuild by setState(), flag is also reset. So always flag is false.
Make it a variable inside the State class
onPressed: (BuildContext context) async {
await showDialog(
context: context,
builder: (context) => Dialog(
...
Navigator.pop()
);
).then((_) => setState(() {
print("Test is this prints");
flag = !flag
));
}

Related

how to have a button build a widget and have it setstate

I currently have a InkWell that builds a custom widget alert dialog when pressed using the build method below.
InkWell(
onTap: () => showDialog<String>(
context: context,
builder: (BuildContext context) => Popup(),
I also need it to set the state of some Bools and Int's when pressed which usually happens when using the setstate method.
can someone please show me how to do both build a widget and setstate when the button is pressed?
what would the code look like?
cheers
Make a function and set bools before you build the dialog. Then call the method in onTap:
buildMyDialog(){
myBool = false;
myInt = 2;
showDialog<String>(
context: context,
builder: (BuildContext context) => Popup(),
);
}
If you need your current UI to use the values, setState before showing dialog in the same method.

Call a method on page pop

I'm pushing a new route like so in my app
Navigator.of(context)
.push<void>(
FilterTypesPage.routeFullScreen(context),
).then(
(value) {
log('PAGGGE POPPED');
},
),
static Route routeFullScreen(BuildContext context) {
return MaterialPageRoute<void>(
settings: const RouteSettings(name: routeName),
builder: (_) => BlocProvider.value(
value: BlocProvider.of<FeatureBloc>(context),
child: const FilterTypesPage(),
),
fullscreenDialog: true);
}
for some reason log('PAGGGE POPPED'); doesn't get called on page close
I'd like to trigger a bloc event or a function when I close this page
You should just call
Navigator.pop(context, someData);
from your RouteSettings where someData is the data you want to pass from the RouteSettings to the former page.
Then from your former page, you can perform your event handling inside the then block. The value inside the then block is the data that was passed from the RouteSettings page.
Alternatively, you can also use async-await instead of then in your former page.
onPressed: () async {
final someData = await Navigator.of(cotext).push(.....);
// Now perform your event handling which will be invoked after you pop `RouteSettings` page.
}

Flutter, refresh screen after await call

Currently the only way I have to refresh the screen is using Navigator.push().
if (response.statusCode == 200) {
print(await response.stream.bytesToString());
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => this.build(context)));
}
But this only adds another screen to the stack of screens.
How can I refresh the screen after calling my print() without having to use Navigator.push()?
Thanks!
You can set your class as Stateful Widget and use:
setState(() {
// Add, edit or delete widgets
// Set a diferent value for some variable
// etc...
});
Or you can still use the Navigator but with the pushReplacement function, for example:
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (BuildContext context) => super.widget));
use setState after request api response data,
setState is a way to dynamically change the UI.
It rebuild all current screen.
We call it inside the State Object class of the StatefulWidget.

refresh previous page on Navigator.pop function

Is there any way to refresh the previous page/ stack when Navigator.pop(context) is called? I need to do the API calling of the previous page to refresh the state of the page. The navigator.pop will sometimes be an alert dialog or maybe a back button. Is there a way to do the API calling? ThankYou.
use the then function after you push another route.
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => MyHomePage(),
),
).then(
(value) {
if (value) {
//refresh here
}
},
);
and when you return to previous screen, provide the pop function a value that determines whether to perform some action.
Navigator.of(context).pop(true);
Previous page
void goToNextPage()async {
var refresh = await Navigator.push(_context, new MaterialPageRoute(
builder: (BuildContext context) => new nextPage(context))
);
if(refresh ) setState((){});
}
NextPage
Navigator.pop(context, true);

disable android back while showModalBottomSheet opened

My widget inside showModalBottomSheet is a textfield , user must fill up correct value in order to proceed next function, I know there is a ready param called isDismissible , however it only disable from taping backdrop, it doesn't diable android back.
return showModalBottomSheet(
context: context,
builder: (BuildContext context) {
...
}
}
you can wrap your widget with WillPopScope
For example:
WillPopScope(
onWillPop: () async => false,
)