Anyone knowing about the basics of how Flutter decides what to redraw when
setState is called will know about keys. So in theory, if you have unique keys for your widgets, you will get your UI to redraw, right?
Image not refreshing
The problem occurred when I was building a very basic UI for a prototype. Just a
Image widgets inside. The
Image widgets are read from a location in the disk.
ListView.builder( itemCount: pages.length, itemBuilder: (BuildContext context, int index) => Image.file( File(pages[index]), key: UniqueKey(), ));
Since the widget has a
UniqueKey(), I was expecting that every time
setState is called, even if
pages array remained the same, the latest images would be shown in the UI.
This was not the case though. No matter what I tried, the same image that was loaded the first time would be displayed in the UI, even if I changed the contents of the files (but not their file name or location).
If I tried to create new images and use different names every time, then the UI would work as expected. But this was quite inconvenient and unnecessary. Was there something I was missing on how the framework worked?
It turns out that Flutter is using a global image cache that I was not aware of. Of course, this was mentioned in
Image.file() constructor DartDoc but I was too lazy to read. Other people hit this issue as well.
The framework was indeed re-drawing the widgets since they had a
UniqueKey(). It was just using the in-memory copy of the image because the image path was the same and was considering it the same image.
The solution is just to clear the cache in combination with setting a
imageCache.clear(); imageCache.clearLiveImages(); [...] ListView.builder( itemCount: pages.length, itemBuilder: (BuildContext context, int index) => Image.file( File(pages[index]), key: UniqueKey(), ));
Hopefully, I will save someone else a few hours of debugging. Happy coding!