I have one outer StatefulWidget and one inner StatefulWidget. When I use setState() on the outer Widget, the inner Widget's build function gets rerun. Is there a way to also trigger the initState method? This is the inner Widget:
class _Image extends StatefulWidget {
final String _imageId;
_Image(this._imageId);
@override
State createState() => new _ImageState();
}
class _ImageState extends State<_Image> {
ImageResponse image;
@override
void initState() {
super.initState();
// fetch image using the provided imageId
fetchImage(widget._imageId).then((ImageResponse imageResponse) {
setState(() {
image = imageResponse;
});
});
}
@override
Widget build(BuildContext context) {
return new Container(
width: 350.0,
height: 350.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8)),
color: Color(0xffFFFFFF),
image: image != null ? DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(image.downloadURL)
) : null,
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.25),
spreadRadius: 0,
blurRadius: 4,
offset: Offset(0, 4)
)
]
),
);
}
}
A very simple Widget as you can see. You can provide an imageId and the Widget will fetch the data of that image and will display it. Now I want that when the outer Widget get's updated, not only the build function get's rerun but also the initState function, so that the new image-data for that imageId can be fetched.
You can use a FutureBuilder to show the view with an image loader until the image is loaded. Each time you launch this widget, it will call for the image.
class _Image extends StatefulWidget {
final String _imageId;
_Image(this._imageId);
@override
State createState() => new _ImageState();
}
class _ImageState extends State<_Image> {
ImageResponse image;
@override
void initState() {
super.initState();
}
Future<ImageResponse> loadImage() async {
ImageResponse res = await fetchImage(widget._imageId);
return res;
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: loadImage(),
builder: (context, snapshot) {
if (snapsnot.connectState==ConnectionState.done) {
return new Container(
width: 350.0,
height: 350.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8)),
color: Color(0xffFFFFFF),
image: image != null ? DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(snapshot.data.downloadURL)
) : null,
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.25),
spreadRadius: 0,
blurRadius: 4,
offset: Offset(0, 4)
)
]
),
);
} else {
// paint whatever you want to the screen while the image loads. I'm using an empty container as an example
return Container();
}
}
)
}
}
User contributions licensed under CC BY-SA 3.0