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.jsonString 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
相关产品推荐
相关产品推荐

