在FutureBuilder中的setState。

14 浏览
0 Comments

在FutureBuilder中的setState。

我想在FutureBuilder中使用setState,但一直收到 "setState()或markNeedsBuild()在构建期间被调用" 的错误提示。我已经将ratio声明为全局变量,并希望更新ratio的值。只有在成功获取到图像的宽度和高度后,才能计算ratio的值。

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 completer = new Completer();

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,但是由于需要更新全局变量,有什么解决方案呢?

0
0 Comments

问题出现的原因是在构建小部件时每次都调用了selectImage方法,解决方法是将调用移动到initState方法中,这样可以在进行所有计算后再调用setState。具体的解决方法如下所示:

void initState() {

super.initState();

setup();

}

setup() async {

var data = await _bloc.selectImage();

// 进行使用data的计算

// 调用setState

}

在调用selectImage方法之前,请确保已经初始化了_bloc对象。

更多详细信息,请参考这里

0