Reputation: 1440
I've made a simple widget with a progress bar of 10 steps. When I click a button, that progress bar increases:
class SoundBarWidget extends StatefulWidget {
SoundBarWidget({
Key key,
this.height,
this.level,
}) : super(key: key);
double height;
double level = 0;
@override
_SoundBarWidgetState createState() => _SoundBarWidgetState();
}
class _SoundBarWidgetState extends State<SoundBarWidget> {
double barHeight() {
return widget.height == null
? DEFAULT_SOUNDBAR_HEIGHT
: (widget.height > 0 ? widget.height : DEFAULT_SOUNDBAR_HEIGHT);
}
@override
Widget build(BuildContext context) {
Widget w;
if (widget.level == null) {
widget.level = 50;
}
if (widget.level > 90) {
w = Image.asset('soundbar11.png', height: barHeight());
} else if (widget.level > 80) {
w = Image.asset('soundbar10.png', height: barHeight());
} else if (widget.level > 70) {
w = Image.asset('soundbar9.png', height: barHeight());
} else if (widget.level > 60) {
w = Image.asset('soundbar8.png', height: barHeight());
} else if (widget.level > 50) {
w = Image.asset('soundbar7.png', height: barHeight());
} else if (widget.level > 40) {
w = Image.asset('soundbar6.png', height: barHeight());
} else if (widget.level > 30) {
w = Image.asset('soundbar5.png', height: barHeight());
} else if (widget.level > 20) {
w = Image.asset('soundbar4.png', height: barHeight());
} else if (widget.level > 10) {
w = Image.asset('soundbar3.png', height: barHeight());
} else if (widget.level > 0) {
w = Image.asset('soundbar2.png', height: barHeight());
} else {
w = Image.asset('soundbar1.png', height: barHeight());
}
return w;
}
}
The problem is that, the first time a new .png is loaded, Flutter renders an empty container for some milliseconds. So what happens is that the progress bar does a little jump. This happens only on the first load of every .png. When that png is re-rendered it does not happen, so I guess it has something to do with the image not being on cache.
So, how do I load/cache flutter .png images before using them?
Upvotes: 0
Views: 363
Reputation: 4854
The precacheImage
function is specifically meant to be used to load an image before it's actually drawn:
List<String> _images = ['soundbar1.png', 'soundbar2.png', 'soundbar3.png'];
@override
void initState() {
super.initState();
Future.delayed(Duration.zero, () {
this._loadImages();
});
}
Future<void> _loadImages() async {
_images.forEach((image) async {
await precacheImage(AssetImage(image));
});
}
You can read more about it in the official documentation
Upvotes: 2