【问题标题】:How do I tell when a NetworkImage has finished loading?如何判断 NetworkImage 何时完成加载?
【发布时间】:2018-03-01 18:46:26
【问题描述】:

我有一个NetworkImage,我想知道它何时完成加载。我该怎么做?

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    您可以通过resolve 获取ImageStreamaddListenerImageStream

    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,
            ),
          ),
        );
      }
    }
    

    【讨论】:

    • 我需要以某种方式关闭这个 imageStream 吗?
    • 监听器现在必须写成这样:_image.image.resolve(ImageConfiguration()).addListener(ImageStreamListener((ImageInfo info, bool syncCall) => completer.complete()));跨度>
    【解决方案2】:

    您可以使用 ImageStreamListener 来做到这一点。 ImageStreamListener 的第一个参数是 ImageListener 回调,当图像完全加载时调用。

     var _image = NetworkImage("URL");
    
     _image.resolve(ImageConfiguration()).addListener(
        ImageStreamListener(
          (info, call) {
            print('Networkimage is fully loaded and saved');
            // do something
          },
        ),
      );
    

    【讨论】:

      【解决方案3】:

      我在flutter官方demo中找到了这个方法,希望对你有所帮助。

      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】:

        您可以使用loadingBuilder,它为Image.Network 提供颤振功能

        以下示例使用loadingBuilder 显示CircularProgressIndicator,同时通过网络加载图像。

           Image.network(
              'https://example.com/image.jpg',
              loadingBuilder: (BuildContext context, Widget child,
                  ImageChunkEvent loadingProgress) {
                if (loadingProgress == null) return child;
                return Center(
                  child: CircularProgressIndicator(
                    value: loadingProgress.expectedTotalBytes != null
                        ? loadingProgress.cumulativeBytesLoaded /
                        loadingProgress.expectedTotalBytes
                        : null,
                  ),
                );
              },
            )
        

        【讨论】:

          【解决方案5】:

          2021 年更新

          _image.image.resolve(ImageConfiguration())
               .addListener(ImageStreamListener((ImageInfo info, bool syncCall) {
          
          // DO SOMETHING HERE
          
          completer.complete();
          
          });
          

          【讨论】:

          • 也适用于Image.fileImage.memory
          【解决方案6】:

          感谢您的评论,这有助于解决如何知道图像是否加载的情况希望帮助

          我使用 StatefulWidget 需要根据您的 AffichScreen 进行编辑

          情况:

          -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,
                                                      ),
                                      ),
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-09-18
            • 1970-01-01
            • 2021-12-04
            • 1970-01-01
            相关资源
            最近更新 更多