Reputation: 2252
Let's say I have an image on the device's disk and load it on the screen providing its path to a FileImage
.
I edit that image and save it on the same path expecting calling the setState(() {})
function will reload it. But it doesn't.
I tried clearing the image cache by calling imageCache.clear()
function and also imageProvider.evict()
but no difference.
If I close that page and open it again, I see the updated images.
I assume the images that are being displayed on the screen are in the memory, if my assumption is correct, how to reload it?
Upvotes: 17
Views: 7909
Reputation: 129
Sadly, none of the above solutions worked for me for the use case. Only solution for me was deleting the existing file, and saving the new file under the same deleted filename.
// Delete the existing file
await File(imagePath).delete();
// Copy the image to the path
await file.copy(imagePath);
Upvotes: 0
Reputation: 580
Just another (late) workaround
ImageProvider loadImage(String filePath) {
final File file = File(filePath);
return MemoryImage(file.readAsBytesSync());
}
Upvotes: 0
Reputation: 152
The other answers were missing step 2. Full explanation here.
imageCache.clear();
and then imageCache.clearLiveImages();
when the new image needs to be reloaded.Image(image: FileImage(File(pathName)), key: ValueKey(File(pathName).lengthSync()))
The image should reload after.
Upvotes: 0
Reputation: 1513
This is a bit ugly workaround, but it works for me. Here we're resetting image cache + force reloading image from disk:
class _MyAppState extends State<MyApp> {
final imageKey = GlobalKey();
bool forceLoad = false;
@override
Widget build(BuildContext context) {
final app = MaterialApp(
home: Scaffold(
body: forceLoad
? Image.memory(currentFile.readAsBytesSync(), key: imageKey)
: Image.file (currentFile, key: imageKey),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.refresh),
onPressed: () async {
await (imageKey.currentWidget as Image).image.evict(); // reset cache for current image
setState(() {
forceLoad = true; // reloading current image from disk
});
},
)
)
);
forceLoad = false;
return app;
}
}
Upvotes: 0
Reputation: 129
Already tested - Adding the both image cache commands will solve the problem.
imageCache.clear();
imageCache.clearLiveImages();
});
Upvotes: 3
Reputation: 1578
This is also working for me:
Image previewImage = Image.file(
File(scenePreviewFilename),
);
And when pressing a button or something just evict the cached image from imageCache like this:
setState(() {
imageCache.evict(previewImage.image, includeLive: true);
});
PS: I had some issues getting this to work(similar to the initial post) because I was generating the image in another thread and the image was loaded before it was generated, resulting in the imageCache appearing not to have an effect ... so make sure you are not in this race situation.
Upvotes: 3
Reputation: 9883
I know I'm a bit late, but I used this workaround:
_tmpImageFile.existsSync() ? Image.memory(
Uint8List.fromList(_tmpImageFile.readAsBytesSync()),
alignment: Alignment.center,
height: 200,
width: 200,
fit: BoxFit.contain,
) : Container(),
Upvotes: 6
Reputation: 18612
Would changing the key of the Image do the trick?
Set a key to the image
Image.file(
_imageFile,
key: _key,
fit: BoxFit.cover,
),
and change the key every time you change _imageFile, let's set it to timestamp for example
setState(() {
_imageFile = newImageFile;
_key = DateTime.now().millisecondsSinceEpoch;
});
Upvotes: 0