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



如何加载AssetImage或检查它是否存在?数据来自api,所以我不能将所有文件路径都列为常量。

例如,路径可能是"assets/images/${card.imageType}.png",其中card.inageType是一个变量。

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

对于我的getImage功能,我尝试了两种,但无法使用

方法1:使用文件:existsSync方法始终为false。请记住,等待异步无法工作,因为图像小部件预计不会有未来的

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

方法2:使用try-catch:没有捕获异常

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

您可以使用类似的方法来检查资产是否存在:

// 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

至于没有被捕获的异常,这可能意味着Error被抛出,这与Exception的不同

您可以使用以下代码检查文件是否异步存在:

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

为此,我创建了一个异步方法来检查文件是否存在,如果文件不存在,则加载一个默认值,在我的UI中,我使用未来的生成器。。有点像。

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块的级别,所以我想它可以被删除。

您不能将资产图像用于从网络获取的图像。

一旦你从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),)

Think userImgUrl是一个字符串,用于保存可以在互联网上找到的图像的url。若图片为空,只需在圆圈内显示一个文本头像。如果图像可从API获得,则在NetworkImage((中显示图像

最新更新