【发布时间】:2019-12-28 12:19:07
【问题描述】:
我正在尝试从网络加载图像,然后将其传递给 ExtendedRawImage 作为已完成的未来 Image 进行裁剪。
问题在于,每张新图像都使用(我认为)同一个未来实例来检查图像是否已加载,这就是为什么它在每张新图像上显示CircularProgressIndicator。
我尝试过和没有解决我的问题:
- 为未来添加钥匙,
- 将功能移至全新的
StatefulWidget小部件。
我现在正在使用的代码和 gif:
AnimatedList(
key: _sListKey,
physics: BouncingScrollPhysics(),
controller: _sScrollCtrl,
padding: EdgeInsets.all(5),
initialItemCount: sData.length,
itemBuilder: (context, index, animation) {
final vehicle = sData[index];
final color = defaultRegions.contains(vehicle.region)
? Colors.grey
: Colors.blue;
return _dataContainer(
vehicle, animation);
},
)
class CropImage extends StatefulWidget {
final Vehicle vehicle;
CropImage({Key key, this.vehicle}) : super(key: key);
@override
_CropImageState createState() => _CropImageState();
}
class _CropImageState extends State<CropImage> {
Future<ImageInfo> _imageInfo;
@override
void initState() {
super.initState();
NetworkImage image = NetworkImage(widget.vehicle.image);
Completer<ImageInfo> completer = Completer();
image
.resolve(new ImageConfiguration())
.addListener(ImageStreamListener((ImageInfo info, bool _) {
completer.complete(info);
}));
_imageInfo = completer.future;
}
@override
Widget build(BuildContext context) {
return AspectRatio(
aspectRatio: widget.vehicle.vehicleRegion.width /
widget.vehicle.vehicleRegion.height,
child: FutureBuilder(
// key: UniqueKey(),
future: _imageInfo,
builder: (context, AsyncSnapshot<ImageInfo> snapshot) {
if (snapshot.hasData) {
return ExtendedRawImage(
image: snapshot.data.image,
fit: BoxFit.cover,
soucreRect: Rect.fromLTWH(
widget.vehicle.vehicleRegion.x,
widget.vehicle.vehicleRegion.y,
widget.vehicle.vehicleRegion.width,
widget.vehicle.vehicleRegion.height,
),
);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
),
);
}
}
UPDATE_1:_dataContainer() 包含CropImage 小部件,我用常规容器包装了它。另外作为旁注,我正在使用 websocket 将数据传递给 AnimatedList,方法是使用 _sListKey.currentState.insertItem(0) 将其插入列表顶部。
UPDATE_2 我想我已经缩小了一个问题的范围。如果我在AnimatedList 中使用任何类型的FutureBuilder(如下所示),则会产生同样的问题(添加“密钥”或移动到另一个Statefull 小部件并不能解决问题)。
FutureBuilder(
future: http.get(vehicle.image),
builder: (context, AsyncSnapshot<http.Response> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Image.memory(snapshot.data.bodyBytes);
} else {
return CircularProgressIndicator();
}
},
),
UPDATE_3:似乎核心问题来自setState() 调用。因为我使用weboskcet 将数据传递给视图,所以每次有新数据进来时,都会调用setState() 来通知AnimatedList 或Listview 重新加载视图,这会强制FutureBuilder 刷新.但是知道这并不能解决我的问题。
@override
void initState() {
super.initState();
ws.dataCallback = (vehicle, status) {
switch (status) {
case 0:
setState(() {});
break;
}
};
}
注意:作为请求,创建了我的问题的示例存储库 (link to repo)。
【问题讨论】:
-
您使用的是最新版本的插件吗?你试过其他的裁剪插件吗?
-
@MikhailPonkin 我也尝试使用Image 包来裁剪图像,但它也产生了同样的问题。
-
你会考虑分享一个示例项目吗?遵循代码片段有点困难。
-
@GazihanAlankus 我用我的问题的示例存储库更新了问题。