dart 检查AssetImage资产路径是否存在

b1payxdu  于 2023-09-28  发布在  其他
关注(0)|答案(4)|浏览(106)

如何加载AssetImage或检查它是否存在?数据来自API,所以我不能将所有文件路径作为常量列出。
作为示例,路径可以是“assets/images/${card·imageType}·png”,其中card·inageType是变量。

...
child: Image(
       height: 60.0,
       image: Utils.getImage('assets/images/card-${card.category}.png'),
       ),
...

对于我的getImage函数,我尝试了两种方法,但都不起作用

方法一:使用文件:existsSync方法始终为false。请记住,await async不能工作,因为Image小部件预期的不是Future

static dynamic getImage(path) {
    File f = File(path);
    return f.existsSync()
        ? FileImage(f)
        : const AssetImage('assets/images/default.png');
  }
}

方法二:使用try catch:异常未被捕获

static AssetImage getImage(path) {
    AssetImage image;

    try {
      image = AssetImage(path);
    } catch (e) {
      image = const AssetImage('assets/images/default.png');
    }

    return image;
  }
flseospp

flseospp1#

您可以使用类似于以下内容来检查资产是否存在:

// example: 'assets/check_green.png' 
Future<bool> checkIfAssetExists(String fullAssetPath) async {
  final Uint8List encoded = Utf8Codec()
      .encoder
      .convert(Uri(path: Uri.encodeFull(fullAssetPath)).path);
  // returns null if an asset is not found
  final ByteData? asset = await ServicesBinding.instance!.defaultBinaryMessenger
      .send('flutter/assets', encoded.buffer.asByteData());
  return asset != null;
}

您可以在您的initState中运行此命令,然后放心地使用AssetImage
至于未捕获到的异常,这可能意味着抛出了一个与Exception不同的Error

uujelgoq

uujelgoq2#

你可以用下面的代码检查一个文件是否异步存在:

import 'dart:io';
File("path/to/file").exists()

或同步检查:

import 'dart:io';
File("path/to/file").existsSync()

更新:

从initState调用isPathExists()函数。
AssetBundle用于获取资产文件夹中的资产。你可以插入任何东西到 * menubanner.png * 如果它存在,图像将被分配给变量,如果它不存在,一个异常抛出。

late Image image;
  isPathExists() async {
    try {
      var assetbundle = DefaultAssetBundle.of(context);
      ByteData res = await assetbundle.load('assets/images/menubanner.png');
      var list = Uint8List.sublistView(res);
      setState(() {
        image = Image.memory(list);
      });
    } catch (exception) {
      print(exception);
    }
  }
vkc1a9a2

vkc1a9a23#

为此,我创建了一个future builder方法来检查文件是否存在,如果文件不存在,则加载默认值,并且在我的UI中,我使用了future builder。差不多。

static Future<ImageProvider<Object>> loadImage(
  BuildContext context, String imagePath) async {
try {
  final bundle = DefaultAssetBundle.of(context);
  await bundle.load(imagePath);
  return AssetImage(imagePath);
} catch (e) {
  return const AssetImage("assets/no_image_placeholder.png");
}}

然后在UI中,

SizedBox(
          height: 100.0,
          width: 160.0,
          child: FutureBuilder(
            future: ProductFallbackErrorImage.loadImage(context,
                "assets/product_images/${productName.toLowerCase()}.jpg"),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return Container(
                  height: 100.0,
                  width: 160.0,
                  decoration: BoxDecoration(
                    borderRadius: const BorderRadius.only(
                      topLeft: Radius.circular(8.0),
                      topRight: Radius.circular(8.0),
                    ),
                    image: DecorationImage(
                      image: snapshot.data as ImageProvider<Object>,
                      fit: BoxFit.fill,
                    ),
                  ),
                );
              } else if (snapshot.hasError) {
                'snapshot has error with value ${snapshot.error.toString()}'
                    .log();
                return Container(
                  height: 100.0,
                  width: 160.0,
                  decoration: const BoxDecoration(
                    borderRadius: BorderRadius.only(
                      topLeft: Radius.circular(8.0),
                      topRight: Radius.circular(8.0),
                    ),
                    image: DecorationImage(
                      image: AssetImage("assets/no_image_placeholder.png"),
                      fit: BoxFit.fill,
                    ),
                  ),
                );
              } else {
                return const CircularProgressIndicator();
              }
            },
          ),
        ),

错误块永远不会被执行,因为我们正在处理catch块的级别,所以我想可以删除它。

bkkx9g8r

bkkx9g8r4#

不能将资源图像用于从网络获取的图像。
一旦你从你的API得到响应。将图像的url存储在String变量中。通常来自API的图像存储在Web服务中。
当你有图像的url时,只需使用NetworkImage小部件,例如:

SizedBox(
     width: 75,
     height: 75,
     child: userImgUrl.isEmpty
     ? const CircleAvatar(
     child: Text('Avatar'))
     : CircleAvatar(
          radius: 30,
          backgroundImage: NetworkImage(
                             userImgUrl),
                             backgroundColor: Colors.transparent),)

假设userImgUrl是一个String,它保存了可以在互联网上找到的图像的URL。如果图像是空的,只是显示一个文本内圈头像。如果API有镜像,则在**NetworkImage()**中显示镜像

相关问题