1

我有一个来自服务器的 base64 图像列表,我有一个类可以将它们缓存在临时文件夹中。

由于缓存过程可能需要一些时间,特别是当图像很大时,图像不会在 UI 中显示。

我的模型类中有一个loading属性,起初是true,当缓存过程完成时它变成false.

这是我的缓存模型类:

class ImageCaching {
  int timestamp;
  String base64;
  File tempFile;
  bool loading;
  ImageCaching({this.base64, this.timestamp, this.loading = true}) {
    this.createTempFile();
  }

  createTempFile() async {
    Uint8List bytes = base64Decode(this.base64);
    final appDir = await getTemporaryDirectory();
    File file = File('${appDir.path}/${this.timestamp}.jpg');
    await file.writeAsBytes(bytes);
    this.tempFile = file;
    this.loading = false;
  }
}

这是我展示图片的地方:

return imageCache.loading
          ? Text('Loading')
          : imageCache.tempFile != null
              ? Image.file(imageCache.tempFile)
              : Image.asset(
                  defaultImg,
                  fit: boxFit,
                );

这是我列表的模型类:

class Image {
  int timestamp;
  String base64;
  ImageCaching imageCache;
  Image({
    @required this.timestamp,
    this.base64,
  }) {
    this.imageCache =
        this.base64 != null ? ImageCaching(base64: this.base64, timestamp: this.timestamp) : null;
  }
}

我在 redux 商店中有一个此类的列表。和项目。

但有时取决于图像大小,图像未在 UI 中显示和加载文本,甚至显示缓存已完成。

我想在loading属性变为false.

我尝试使用ChangeNotifier它并且它有效,但我认为这不是一个好方法:

缓存模型重写ChangeNotifier

class ImageCaching with ChangeNotifier {
  int timestamp;
  String base64;
  File tempFile;
  bool loading;
  ImageCaching({this.base64, this.timestamp, this.loading = true}) {
    this.createTempFile();
  }

  createTempFile() async {
    Uint8List bytes = base64Decode(this.base64);
    final appDir = await syspaths.getTemporaryDirectory();
    File file = File('${appDir.path}/${this.timestamp}.jpg');
    await file.writeAsBytes(bytes);
    this.tempFile = file;
    this.loading = false;
    notifyListeners();
  }
}

在小部件中我试试这个:

image.imageCache?.addListener(() {
  setState(() {});
});

我想我可能在大列表和弱电话中遇到内存问题。

正如文档中所说:

ChangeNotifier 针对少量(一或两个)侦听器进行了优化。添加和删​​除监听器是 O(N),调度通知是 O(N²)(其中 N 是监听器的数量)。

loading我将在成为之后删除侦听器false

4

0 回答 0