检查图像是否已加载到 flutter 中的 Image.network 小部件中

问题描述 投票:0回答:6

我是 Flutter 新手。我尝试使用

image.network
小部件加载网络图像。它工作正常,但有时加载需要时间。我在点击期间向
image.network
添加了点击侦听器,我需要根据重定向页面所需的结果来检查图像是否已完全加载。如何检查图像是否加载?

代码:

new Image.network('http://via.placeholder.com/350x150')

如有任何帮助,我们将不胜感激,提前谢谢您

image flutter dart image-loading flutter-widget
6个回答
79
投票

您可以使用 flutter 的内置功能

loadingBuilder
来实现
Image.Network

我是这样做的:

Image.network(imageURL,fit: BoxFit.cover,
  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,
      ),
    );
  },
),

29
投票

对于此类问题,最好使用 cached_network_image 因此您可以在加载图像时提供占位符,并在资源加载失败时提供错误小部件

String url = "http://via.placeholder.com/350x150";
CachedNetworkImage(
       imageUrl: url,
       placeholder: (context,url) => CircularProgressIndicator(),
       errorWidget: (context,url,error) => new Icon(Icons.error),
     ),

9
投票

对于不需要缓存图像的人可以使用meet_network_image包,

套餐基本用法:

                MeetNetworkImage(
                  imageUrl:
                      "https://random.dog/3f62f2c1-e0cb-4077-8cd9-1ca76bfe98d5.jpg",
                  loadingBuilder: (context) => Center(
                        child: CircularProgressIndicator(),
                      ),
                  errorBuilder: (context, e) => Center(
                        child: Text('Error appear!'),
                      ),
                )

此外,您可以使用

FutureBuilder

自己完成此操作

我们需要通过这种方式通过http调用获取数据,我们需要在导入之前导入http,您还需要添加

pubspec.yaml
并运行命令
flutter packages get

import 'package:http/http.dart' as http;
  FutureBuilder(
    // Paste your image URL inside the htt.get method as a parameter
    future: http.get(
        "https://random.dog/3f62f2c1-e0cb-4077-8cd9-1ca76bfe98d5.jpg"),
    builder: (BuildContext context, AsyncSnapshot<http.Response> snapshot) {
      switch (snapshot.connectionState) {
        case ConnectionState.none:
          return Text('Press button to start.');
        case ConnectionState.active:
        case ConnectionState.waiting:
          return CircularProgressIndicator();
        case ConnectionState.done:
          if (snapshot.hasError)
            return Text('Error: ${snapshot.error}');
          // when we get the data from the http call, we give the bodyBytes to Image.memory for showing the image
          return Image.memory(snapshot.data.bodyBytes);
      }
      return null; // unreachable
    },
  );

2
投票

这样就会开始加载,然后会显示图片加载的加载情况,然后是图片。如果您不想使用外部库,这是最好的选择。

Image.network(
  imgUrl,
  height: 300,
  fit: BoxFit.contain,
  frameBuilder: (_, image, loadingBuilder, __) {
    if (loadingBuilder == null) {
      return const SizedBox(
        height: 300,
        child: Center(child: CircularProgressIndicator()),
      );
    }
    return image;
  },
  loadingBuilder: (BuildContext context, Widget image, ImageChunkEvent? loadingProgress) {
    if (loadingProgress == null) return image;
    return SizedBox(
      height: 300,
      child: Center(
        child: CircularProgressIndicator(
            value: loadingProgress.expectedTotalBytes != null
                ? loadingProgress.cumulativeBytesLoaded / loadingProgress.expectedTotalBytes!
                : null,
        ),
      ),
    );
  },
  errorBuilder: (_, __, ___) => Image.asset(
    AppImages.withoutPicture,
    height: 300,
    fit: BoxFit.fitHeight,
  ),
)

1
投票

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

我使用 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,
                                            ),
                            ),

0
投票

如何在 flutter/dart 中以异步方式加载图像。 需要知道图片是否加载

© www.soinside.com 2019 - 2024. All rights reserved.