You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter读取JSON文件展示组件报错:类型不匹配问题求助

Flutter JSON解析错误解决及优化实现

错误原因

你遇到的_TypeError (type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List<dynamic>')错误,本质是JSON结构和代码变量类型不匹配:
你的JSON文件外层是一个包含breeds数组的对象(Map),但代码里直接把整个解析结果当成List来使用(比如breeds.length、breeds[index]的写法),导致类型转换失败。

修复步骤

1. 修正JSON解析逻辑

假设你的JSON结构是:

{
  "breeds": [
    {"name": "波斯猫", "img": "https://example.com/cat1.jpg"},
    {"name": "金毛", "img": "https://example.com/dog1.jpg"}
  ]
}

原来的解析代码如果是直接赋值给List,要改成先取breeds数组:

// 错误写法:直接把Map赋值给List
// List breeds = json.decode(response.body);

// 正确写法:先解析成Map,再取出breeds数组
Map<String, dynamic> jsonData = json.decode(response.body);
List breeds = jsonData['breeds'];

2. 优化列表项(实现圆形图片+文本兜底)

把Image.network改成CircleAvatar,同时添加图片加载失败时的文本兜底:

ListView.builder(
  itemCount: breeds.length,
  itemBuilder: (BuildContext context, int index) {
    final breedData = breeds[index];
    return ListTile(
      leading: CircleAvatar(
        backgroundImage: NetworkImage(breedData['img']),
        // 图片加载失败/为空时显示名称首字母
        child: breedData['img'].isEmpty 
            ? Text(breedData['name'].substring(0, 1)) 
            : null,
      ),
      title: Text(breedData['name']),
      onTap: () {
        // TODO: 跳转到品种详情页
      },
    );
  },
);

3. 进阶:用模型类规范解析(推荐)

作为新手,用模型类可以避免直接操作Map的索引错误,代码更易维护:

第一步:定义Breed模型类

class Breed {
  final String name;
  final String img;

  Breed({required this.name, required this.img});

  // 从Map转成Breed对象
  factory Breed.fromJson(Map<String, dynamic> json) {
    return Breed(
      name: json['name'] ?? '未知品种', // 兜底默认值
      img: json['img'] ?? '',
    );
  }
}

第二步:解析成模型列表

Map<String, dynamic> jsonData = json.decode(response.body);
List<Breed> breeds = (jsonData['breeds'] as List)
    .map((item) => Breed.fromJson(item))
    .toList();

第三步:ListView中使用模型

ListView.builder(
  itemCount: breeds.length,
  itemBuilder: (BuildContext context, int index) {
    final breed = breeds[index];
    return ListTile(
      leading: CircleAvatar(
        backgroundImage: NetworkImage(breed.img),
        child: breed.img.isEmpty 
            ? Text(breed.name.substring(0, 1)) 
            : null,
      ),
      title: Text(breed.name),
      onTap: () {
        // TODO: 跳转到品种详情页
      },
    );
  },
);

额外注意事项

  • 如果是本地JSON文件,需要在pubspec.yaml中配置assets路径:
    assets:
      - assets/db.json
    
    加载方式改为:
    String jsonString = await rootBundle.loadString('assets/db.json');
    Map<String, dynamic> jsonData = json.decode(jsonString);
    
  • 网络图片可以用cached_network_image包优化缓存和错误处理,执行flutter pub add cached_network_image后替换使用:
    leading: CircleAvatar(
      backgroundImage: CachedNetworkImageProvider(breed.img),
      placeholder: (context, url) => CircularProgressIndicator(),
      errorWidget: (context, url, error) => Text(breed.name.substring(0, 1)),
    ),
    

内容的提问来源于stack exchange,提问作者GrayCode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 23:07:51