I have a list of base64 images comes from server and I have a class to cache them in temporary folder.
Because caching process may take some time, images not showing in UI specially when image is large .
I have a loading
property in my model class and at first is true
and when caching process finished it become false
.
This is my cache model class:
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;
}
}
This is where I show Image:
return imageCache.loading
? Text('Loading')
: imageCache.tempFile != null
? Image.file(imageCache.tempFile)
: Image.asset(
defaultImg,
fit: boxFit,
);
This is my model class for my list:
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;
}
}
and I have a list of this class in redux store. and item to it.
But sometimes depends on image size, images not showing in UI and loading text, shows even caching finished.
I want to update UI after loading
property become false
.
I try using ChangeNotifier
and it works, but I don't think this is a good way:
Caching model rewrite this 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();
}
}
and in widget I try this:
image.imageCache?.addListener(() {
setState(() {});
});
I think I can have memory problem in large list and weak phone.
As in doc said:
ChangeNotifier is optimized for small numbers (one or two) of listeners. It is O(N) for adding and removing listeners and O(N²) for dispatching notifications (where N is the number of listeners).
I will remove listener after loading
become false
.