Flutter setState() or markNeedsBuild() called when widget tree was locked
As a workaround wrap your code that calling setState
into WidgetsBinding.addPostFrameCallback:
WidgetsBinding.instance
.addPostFrameCallback((_) => setState(() {}));
That way you can be sure it gets executed after the current widget is built.
This is not a thread problem. This error means that you are calling setState
during the build phase.
A typical example would be the following :
Widget build(BuildContext context) {
myParentWidgetState.setState(() { print("foo"); });
return Container();
}
But the setState call may be less obvious. For example a Navigator.pop(context)
does a setState
internally. So the following :
Widget build(BuildContext context) {
Navigator.pop(context);
return Container();
}
is a no go either.
Looking at the stacktrace it seems that simultaneously with the Navigator.pop(context)
your modal try to update with new data.
Special case of using Scaffold
and Drawer
:
That fail can also happen if you try to rebuild the tree with opened Drawer
. For example if you send a message to a Bloc
that forces rebuilding of the whole page/screen.
Consider to call Navigator.pop(context)
first in your tap handler.