【问题标题】:Flutter rerun initState function of inner StatefulWidgetFlutter重新运行内部StatefulWidget的initState函数
【发布时间】:2021-01-16 11:49:58
【问题描述】:

我有一个外部 StatefulWidget 和一个内部 StatefulWidget。当我在外部 Widget 上使用 setState() 时,内部 Widget 的构建函数会重新运行。有没有办法也触发 initState 方法? 这是内部 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)
          )
        ]
      ),
    );
  }

} 

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

【问题讨论】:

  • 只有在加载小部件后才会调用initState

标签: android ios flutter dart flutter-layout


【解决方案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();
                }
            }
        )
        
        
  }

} 

【讨论】:

  • 谢谢,这正是我想要的!但这是“最佳实践”还是应该尽量避免使用 FutureBuilder?
  • FutureBuilder 似乎是 Flutter 基础包中相当稳定的一部分。 “最佳实践”是一种主观意见。 AFAIK 这与产生这些结果的任何其他方式一样高效。如果其他人认为有“更好”的方法可以做到这一点,我希望他们能找到这篇文章并添加他们的答案。
  • 你能接受我的编辑请求吗,你写的代码不起作用
  • 我没有看到任何编辑请求。也许其他成员在我看到它之前就拒绝了它。
猜你喜欢
  • 2021-07-22
  • 1970-01-01
  • 1970-01-01
  • 2020-08-14
  • 2020-02-25
  • 2021-06-24
  • 2021-11-14
  • 2021-04-08
  • 1970-01-01
相关资源
最近更新 更多