在 futureBuilder 中设置状态

setState in futureBuilder

我想在 FutureBuilder 中使用 setState,但一直在使用

setState() or markNeedsBuild() called during build.

我已将比率声明为全局变量。我想更新比率的值。图片宽高获取成功后才能计算比例。

 Widget _showItem() {
    return FutureBuilder(
        future: _bloc.selectImage(),
        builder: (context, snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.waiting:
              return Center(
                child: CircularProgressIndicator(),
              );
              break;

            case ConnectionState.done:
              if (snapshot.hasData) {
                Image image = new Image.network(snapshot.data);
                Completer<ui.Image> completer = new Completer<ui.Image>();
                image.image.resolve(new ImageConfiguration()).addListener(
                    new ImageStreamListener((ImageInfo image, bool _) {
                  completer.complete(image.image);

                  setState(() {
                num maxHeightRatio = 300 / image.image.height;
                num maxWidthRatio = 400 / image.image.width;
                    this.ratio = maxWidthRatio.coerceAtMost(maxHeightRatio);
                  });
                }));

                return CachedNetworkImage(
                  imageUrl: snapshot.data.toString(),
                  imageBuilder: (context, imageProvider) => Container(
                    decoration: BoxDecoration(
                      image: DecorationImage(
                        image: imageProvider
                      ),
                    ),
                  ),
                  placeholder: (context, url) => CircularProgressIndicator(),
                  errorWidget: (context, url, error) => Icon(Icons.error),
                );
              } else {
                return Image.asset('assets/no_image.png');
              }
              break;

            default:
              return Text("Error");
          }
        });
  }

我知道我们不应该在 FutureBuilder 中使用 setState,但是因为我需要更新全局变量,所以解决这个问题的方法是什么?

最好将以后的调用移至 initState 方法,因为您不想在每次构建小部件时都调用 selectImage 方法。一旦将调用移到构建方法之外,就可以进行所有计算,然后 setState.

void initState() {
  super.initState();
  setup();
}

setup() async {
  var data = await _bloc.selectImage();
  // do calculations using data
  // setState
}

阅读更多相关内容 here