22

I have a NetworkImage and I'd like to know when it's finished loading. How do I do that?

Seth Ladd
  • 112,095
  • 66
  • 196
  • 279

5 Answers5

26

You can resolve to get an ImageStream and addListener to the ImageStream

import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatefulWidget {
  State createState() => new MyAppState();
}

class MyAppState extends State<MyApp> {
  Image _image = new Image.network(
    'https://flutter.io/images/flutter-mark-square-100.png',
  );
  bool _loading = true;

  @override
  void initState() {
    _image.image.resolve(new ImageConfiguration()).addListener((_, __) {
      if (mounted) {
        setState(() {
          _loading = false;
        });
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        body: new Center(
          child: _loading ? new Text('Loading...') : _image,
        ),
      ),
    );
  }
}
Collin Jackson
  • 110,240
  • 31
  • 221
  • 152
  • 2
    do I need to close this imageStream somehow ? – JerryZhou Jul 13 '19 at 01:30
  • 2
    The listener must now be written like: _image.image.resolve(ImageConfiguration()).addListener(ImageStreamListener((ImageInfo info, bool syncCall) => completer.complete())); – madlick71 Aug 20 '20 at 09:10
15

You can do it, with an ImageStreamListener. The first Parameter of the ImageStreamListener is an ImageListener Callback which is called, when the image is fully loaded.

 var _image = NetworkImage("URL");

 _image.resolve(ImageConfiguration()).addListener(
    ImageStreamListener(
      (info, call) {
        print('Networkimage is fully loaded and saved');
        // do something
      },
    ),
  );
timo
  • 151
  • 1
  • 2
5

I find this method in flutter official demo,wish help you.

import 'dart:async';
import 'package:flutter/material.dart';

void _imageLoad() async {

    String imageName = "";

    Image downloadImage = new Image.network(imageName);

    final ImageStream stream = downloadImage.image.resolve(ImageConfiguration.empty);
    final Completer<void> completer = Completer<void>();
    stream.addListener((ImageInfo info, bool syncCall) => completer.complete());
    await completer.future;
    if (mounted) {
      //do sth
    }
}
4

2021 Update

_image.image.resolve(ImageConfiguration())
     .addListener(ImageStreamListener((ImageInfo info, bool syncCall) {

// DO SOMETHING HERE

completer.complete();

});
hysabone.com
  • 2,959
  • 2
  • 15
  • 26
0

thank you for your comment thats help to resolve the situation that how to know if the image is loaded or not hope that help

I use a StatefulWidget need a editing depend on your AffichScreen

situation :

-i have an url that i enter 
 -if url is correct affich the image if not affich an icon
 -if empty affich a Text()
 -precacheImage check if the url is correct if not give an error 
 -and change _loadingimage(bool) to false to affich the icon eror
 -i use a NetworkImage to check with precacheImage and before 
 -affich use a Image.network 

bool _loadingimage;
ImageProvider _image;
Image _imagescreen;

@override
  void initState() {
    _loadingimage = true;
    _imageUrlfocusNode.addListener(_updateImageUrl);
    super.initState();
  }

   @override
  void dispose() {
    _imageUrlfocusNode.removeListener(_updateImageUrl);
    _quantityfocusNode.dispose();
    _imageUrlConroller.dispose();
    _imageUrlfocusNode.dispose();
    super.dispose();
  }

  void _updateImageUrl() {
    setState(() {
      _image = NetworkImage(_imageUrlConroller.text);
    });
    if (!_imageUrlfocusNode.hasFocus) {
      if (_imageUrlConroller.text.isNotEmpty) {
        setState(() {
          loadimage();
        });
      }
    }
  }

  void loadimage() {
    _loadingimage = true;
    precacheImage(_image, context, onError: (e, stackTrace) {
      // log.fine('Image ${widget.url} failed to load with error $e.');
      print('error $e');
      setState(() {
        _loadingimage = false;
        print(_loadingimage);
      });
    });
    if (_loadingimage == true) {
      _imagescreen = Image.network(
        _imageUrlConroller.text,
        fit: BoxFit.fill,
      );
    }
  }



  Container(
                              width: 100,
                              height: 100,
                              margin: EdgeInsets.only(top: 13, right: 11),
                              decoration: BoxDecoration(
                                border: Border.all(
                                  width: 1,
                                  color: Colors.grey,
                                ),
                              ),
                              child:_imageUrlConroller.text.isEmpty
                                      ? Text('enter an url')
                                      : !_loadingimage
                                          ? Container(
                                              child: Icon(Icons.add_a_photo),
                                            )
                                          : Container(
                                              child: _imagescreen,
                                            ),
                            ),
MrMoon
  • 31
  • 1
  • 6