У меня есть список изображений 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
.