【发布时间】:2020-03-03 21:24:20
【问题描述】:
我有一个奇怪的问题,加载从MultiImagePicker转换的文件只有在热重载页面后才能成功加载,否则返回以下错误:
未处理的异常:无法加载资产:/storage/emulated/0/DCIM/Camera/IMG_20191105_104542.jpg
步骤:
initState 从 Firestore 加载现有的图像字符串,这些字符串通过 DefaultCacheManager 缓存到 File 并添加到 tmpGalleryImages 列表中。
添加图片使用 MultiImagePicker,然后将其从 Asset 转换为 File 并添加到 tmpGalleryImages 列表中。
我创建了一个 SetState 按钮来测试重新加载状态,但在调用 SetState 后仍然出现上述错误 - 所以我非常困惑为什么它只在热重新加载后才有效?
注意:通过转换为文件的麻烦,我可以将本地图像(资产)和 Firestore 图像(字符串)合并到一个可以编辑并重新上传到 Firestore 的列表中
initState:
@override
void initState() {
super.initState();
setState(() {
_galleryBloc.getGalleryImages(
docRef: Firestore.instance.collection("galleries").document("gal_${widget.docId}"),
tmpGalleryImages: widget.tmpGalleryImages,
callback: widget.callback);
});
}
StreamBuilder:
@override
Widget build(BuildContext context) {
return StreamBuilder<List<File>>(
stream: _galleryBloc.multipleImageStream,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.none) {
print("none");
}
if (snapshot.connectionState == ConnectionState.waiting) {
print("Waiting");
}
return Column(
children: <Widget>[
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 4),
itemCount: snapshot.data.length < widget.imageLimit ? snapshot.data.length + 1 : snapshot.data.length,
itemBuilder: (context, index) {
return index < snapshot.data.length
? GalleryStepperThumbnail(
file: snapshot.data[index],
onTap: () {
_showGalleryStepperOptions(
context: context,
tmpGalleryImages: snapshot.data,
imageLimit: widget.imageLimit,
file: snapshot.data[index],
fileName: "img_${index + 1}",
);
})
: snapshot.data.length < widget.imageLimit
? InkWell(
onTap: () => _showGalleryStepperOptions(
context: context,
tmpGalleryImages: snapshot.data,
imageLimit: widget.imageLimit,
fileName: "img_${index + 1}",
),
child: Card(
child: Center(
child: Icon(Icons.add),
),
),
)
: Offstage();
},
),
集团:
class GalleryBloc {
final _multipleImageController = StreamController<List<File>>.broadcast();
Stream<List<File>> get multipleImageStream => _multipleImageController.stream;
// -----------------------------------------------------------------------------
// Load existing gallery images
// -----------------------------------------------------------------------------
Future<void> getGalleryImages({DocumentReference docRef, List<File> tmpGalleryImages, Function callback}) async {
try {
await docRef.get().then(
(value) async {
if (value.data != null && tmpGalleryImages.length == 0) {
for (var img in value.data['gallery_images']) {
File fetchedFile = await DefaultCacheManager().getSingleFile(img);
tmpGalleryImages.add(fetchedFile);
}
}
},
);
} catch (e) {
print(e.toString());
}
callback(tmpGalleryImages);
_multipleImageController.sink.add(tmpGalleryImages);
}
// -----------------------------------------------------------------------------
// Convert File to Asset
// -----------------------------------------------------------------------------
Future<File> _convertAssetToFile(String path) async {
final byteData = await rootBundle.load(path);
final file = File(path);
await file.writeAsBytes(byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
return file;
}
// -----------------------------------------------------------------------------
// Select Multiple Images
// -----------------------------------------------------------------------------
Future<void> pickMultipleImages({List<File> tmpGalleryImages, int imageLimit, Function callback}) async {
try {
await MultiImagePicker.pickImages(
maxImages: imageLimit - tmpGalleryImages.length,
).then((chosenImages) async {
for (var path in chosenImages) {
await _convertAssetToFile(await path.filePath).then(
(convertedFile) {
tmpGalleryImages.add(convertedFile);
},
);
}
});
} on Exception catch (e) {
print(e.toString());
}
_multipleImageController.sink.add(tmpGalleryImages);
callback(tmpGalleryImages);
}
如果有人能就我哪里出错提供一些指导,我将不胜感激!
根据 IGOR 的回答(工作)更新代码:
// -----------------------------------------------------------------------------
// Convert File to Asset
// -----------------------------------------------------------------------------
Future<File> _convertAssetToFile(String path) async {
final file = File(path);
return file;
}
【问题讨论】:
标签: flutter