Margareth Reena
Margareth Reena

Reputation: 1440

How to load/cache .png on Flutter?

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

Answers (1)

Stefano Amorelli
Stefano Amorelli

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

Related Questions