Обновить пользовательский интерфейс после изменения свойства в классе модели - PullRequest
1 голос
/ 25 мая 2020

У меня есть список изображений base64, поступающих с сервера, и у меня есть класс для их кеширования во временной папке.

Поскольку процесс кеширования может занять некоторое время, изображения не отображаются в пользовательском интерфейсе, особенно когда изображение большое.

У меня есть свойство 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;
  }
}

, и у меня есть список этого класса в Редукс магазин. и элемент к нему.

Но иногда зависит от размера изображения, изображения не отображаются в пользовательском интерфейсе и загрузка текста, показывает даже завершение кеширования.

Я хочу обновить пользовательский интерфейс после 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(() {});
});

Думаю, у меня могут быть проблемы с памятью в большом списке и слабом телефоне.

Как в do c сказал:

ChangeNotifier оптимизирован для небольшого числа (одного или двух) слушателей. Это O (N) для добавления и удаления слушателей и O (N²) для отправки уведомлений (где N - количество слушателей).

Я удалю слушателя после того, как loading станет false .

...