如何检查图像资产是否存在然后将其用作圆形头像或在圆形头像中写名字的第一个字母

问题描述

我的资产文件夹中有一些图像。我只想检查用户输入的名称是否与图像匹配。如果匹配,那么我想在圆形头像中使用该图像,或者在圆形头像中使用名称的第一个字母。

我的逻辑

我正在尝试通过 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(),);
      },);
  }
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...