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