Flutter重新运行内部StatefulWidget的initState函数

时间:2020-09-30 18:38:37

标签: android ios flutter dart flutter-layout

我有一个外部StatefulWidget和一个内部StatefulWidget。当我在外部Widget上使用setState()时,内部Widget的build函数将重新运行。有没有办法也可以触发initState方法? 这是内部小部件:

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)
          )
        ]
      ),
    );
  }

} 

您可以看到一个非常简单的小部件。您可以提供一个imageId,小部件将获取该图像的数据并将其显示。 现在,我希望在更新外部Widget get时,不仅重新运行build函数,而且要重新运行initState函数,以便可以获取该imageId的新图像数据。

1 个答案:

答案 0 :(得分:1)

您可以使用FutureBuilder来使用图像加载器显示视图,直到图像加载完毕。每次启动此小部件时,它都会调用该图像。

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();
                }
            }
        )
        
        
  }

}