问题描述
我的资产文件夹中有一些图像。我只想检查用户输入的名称是否与图像匹配。如果匹配,那么我想在圆形头像中使用该图像,或者在圆形头像中使用名称的第一个字母。
我的逻辑
我正在尝试通过 rootBundle.loadString()
加载图像。如果图像或路径不存在,则会抛出异常。这就是我知道我需要使用名字的第一个字母的方式。
到目前为止我尝试过的
我的第一种方法只是检查路径是否存在。为此,我使用了以下说明。但它给我总是假的。我找不到合适的理由。
io.File(syncPath).exists();
因此,我使用 rootBundle.loadString()
来捕获异常。
我在互联网上搜索过,但找不到与我的问题相关的解决方案(可能是因为我的搜索技巧不好)
我也尝试过以下解决方案,
我试过将 FutureBuilder
包裹在 Card()
上,例如
child: FutureBuilder<String>(
future: rootBundle.loadString(imagePath),builder: (BuildContext context,snapshot) {
if (snapshot.hasData){
return Card(...)// card and avatar with image
} else {
return Card(...)// card and avatar with first letter of name
}
}
但是,我仍然无法抓住异常。
这是我的代码。
class ItemCardListTile extends StatefulWidget {
final bool tobuy;
final String name;
const ItemCardListTile({
Key? key,required this.tobuy,required this.name,}) : super(key: key);
@override
_ItemCardListTileState createState() => _ItemCardListTileState();
}
class _ItemCardListTileState extends State<ItemCardListTile> {
final log = logger(ItemCardListTile);
String assetsPath = 'assets/images/';
String imageExt = '.png';
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
final String firstLettter = widget.name[0];
AssetImage? imageAssets;
String imagePath = '$assetsPath${widget.name.toLowerCase()}$imageExt';
Future<AssetImage?> checkImageExist(String imagePath) async {
try {
await rootBundle.loadString(imagePath);
imageAssets = AssetImage(imagePath);
} catch (e) {
print(e.toString());
return null;
}
}
return Card(
child: widget.tobuy
? ListTile(
leading: (checkImageExist(imagePath) == null)
? CircleAvatar(
// backgroundImage: imageAssets,child: Text(firstLettter),)
: CircleAvatar(backgroundImage: imageAssets),title: Text(widget.name),)
: const SizedBox(),);
}
}
请帮我解决我的问题。 非常感谢您。
根据@PeterKoltai 的评论更新了我的代码
现在我得到 FormatException: Unexpected extension byte (at offset 0)
。我的图像路径是正确的。我可以使用 AssestImage() 显示圆形头像。
Widget build(BuildContext context) {
final String firstLettter = widget.name[0];
final String _imagePath = 'assets/images/broccoli.png';
Future checkImageExist(String imagePath) async {
try {
return await rootBundle.loadString(imagePath);
} catch (e) {
print(e.toString());
return null;
}
}
return FutureBuilder(
future: checkImageExist(_imagePath),snapshot) {
if (snapshot.hasError != null) {
return Card(
child: widget.tobuy
? ListTile(
leading:CircleAvatar(
child: Text(firstLettter),),)
: const SizedBox(),);
} else
return Container();
},);
}
解决方法
所以最后我解决了这个问题。现在我可以捕获所有错误。 这是我的最终代码。
class ItemCardListTile extends StatelessWidget {
final bool tobuy;
final String name;
ItemCardListTile({
Key? key,required this.tobuy,required this.name,}) : super(key: key);
final log = logger(ItemCardListTile);
String assetsPath = 'assets/images/';
String imageExt = '.png';
@override
Widget build(BuildContext context) {
final String firstLettter = name[0];
final String imagePath = '$assetsPath${name.toLowerCase()}$imageExt';
Future<AssetImage?> checkImageExist(String imagePath) async {
try {
await rootBundle.load(imagePath); // return always null so
return AssetImage(imagePath); // I have added AssetImage
} catch (e) {
print(e.toString());
return null;
}
}
return FutureBuilder(
future: checkImageExist(imagePath),builder: (BuildContext context,snapshot) {
return Card(
child: tobuy
? ListTile(
leading: CircleAvatar(
// here I am checking if image is available then I use it otherwise I write
// first letter of the name
foregroundImage:
(snapshot.data != null) ? AssetImage(imagePath) : null,child: Text(firstLettter),),title: Text(name),)
: const SizedBox(),);
},);
}
}