flutter - 如何显示 Future<File> 图像?

标签 flutter

我的应用程序从 samba(而不是 url)加载图像,然后在本地保存缩略图,所以我不能使用 Image.network(); ,之前我从 samba 加载图像 Uint8List 然后使用 Image.memory(bytes);显示图像,它工作,但我也必须将它与本地缓存结合起来,所以我用 flutter_cache_manager 包保存图像文件 DefaultCacheManager() (使用 (await DefaultCacheManager().getFileFromCache()).file ),但问题是 DefaultCacheManager()只能返回Future<File>缓存而不是 File ,所以我不能使用 Image.file(cacheFile)显示图像。

我必须尝试 FutureBuilder问题解决了,但是会导致图片显示出现闪退。

我考虑过使用 FadeInImage并制作我自己的 ImageProvider满足我的需要,但我很难编写 ImageProvider。

总而言之,我想做这样的事情:

Image.futureFile(Future<File>)

使用 DefaultCacheManager() 返回的 Future 缓存显示本 map 片。如果解决不了(比如本地缓存文件api不应该返回Future),我会考虑使用其他缓存库。

最佳答案

最后我得到了一个自定义的ImageProvider,它指的是FileImage,我不擅长这个所以它可能有问题(例如我不用 gif 测试它)。毕竟,现在图像闪烁比 FutureBuilder 解决方案更好。

class CacheImageProvider extends ImageProvider<CacheImageProvider> {
  final String fileId;//the cache id use to get cache

  CacheImageProvider(this.fileId);

  @override
  ImageStreamCompleter load(CacheImageProvider key, DecoderCallback decode) {
    return MultiFrameImageStreamCompleter(
      codec: _loadAsync(decode),
      scale: 1.0,
      debugLabel: fileId,
      informationCollector: () sync* {
        yield ErrorDescription('Path: $fileId');
      },
    );
  }

  Future<Codec> _loadAsync(DecoderCallback decode) async {
    // the DefaultCacheManager() encapsulation, it get cache from local storage.
    final Uint8List bytes = await (await CacheThumbnail.getThumbnail(fileId)).readAsBytes();

    if (bytes.lengthInBytes == 0) {
      // The file may become available later.
      PaintingBinding.instance?.imageCache?.evict(this);
      throw StateError('$fileId is empty and cannot be loaded as an image.');
    }

    return await decode(bytes);
  }

  @override
  Future<CacheImageProvider> obtainKey(ImageConfiguration configuration) {
    return SynchronousFuture<CacheImageProvider>(this);
  }
  
  //the custom == and hashCode is need, because the ImageProvider use to get the memory cache.
  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType) return false;
    bool res = other is CacheImageProvider && other.fileId == fileId;
    return res;
  }

  @override
  int get hashCode => fileId.hashCode;

  @override
  String toString() => '${objectRuntimeType(this, 'CacheImageProvider')}("$fileId")';
}

并使用它:

Image(image: CacheImageProvider(_data[index].fileId))

关于flutter - 如何显示 Future<File> 图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65917811/

相关文章:

Flutter-网络镜像到文件

flutter - 如何在 Flutter 中创建 GridView 布局

flutter - Dart 中的空安全性是什么?

flutter - 如何向下扩展定位的容器?

android - Flutter:生成释放 SHA1 指纹

android - 如何在文本字段 flutter 中设置虚拟键盘的数据

dart - Flutter showDialog、AlertDialog背景渐变。

ios - 更新 flutter 后面临构建问题

api - Dio(Dart 的 Http 客户端)获取请求不适用于拦截器

Flutter Color.RGB 和 adobe XD 具有相同的颜色值不匹配?