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

Flutter解析本地JSON出现_InternalLinkedHashMap类型错误

问题根因

你遇到的_InternalLinkedHashMap<String, dynamic> is not a subtype of Iterable<dynamic>报错,本质是JSON解析的取值层级和你真实的JSON结构不匹配:
当前你的recipe.json外层是带data字段的普通JSON对象,json.decode(response)执行完成后,返回的result本身是Map<String, dynamic>类型,不支持直接for循环遍历。原代码直接对这个Map做遍历操作,自然会触发类型不匹配异常。
哪怕异常没有抛出,这种写法也只会遍历到Map的键名(也就是字符串"data"),完全拿不到列表里的真实食谱数据。

可直接运行的调整方案
  • 第一步:从解码后的外层Map中取出data字段对应的食谱列表,作为遍历的数据源,解决当前的类型报错
  • 第二步:复用已经写好的RecipeModel.fromJson工厂构造方法,去掉循环中重复手写字段赋值的冗余代码,保持模型类的设计一致性
  • 第三步:异步数据解析完成后调用setState触发页面重建,保证解析完成的列表能正常传递给GridView组件渲染

调整后的完整逻辑如下:

// 在State类中提前定义成员变量存储解析结果,方便GridView直接引用
List<RecipeModel> recipeList = [];

Future<void> getRecipeData() async {
  String response = await DefaultAssetBundle.of(context)
      .loadString('assets/json/recipe.json');
  // 解码外层JSON对象
  final decodedRoot = json.decode(response) as Map<String, dynamic>;
  // 取出data字段对应的原始列表,做空值兜底
  final rawList = decodedRoot['data'] as List<dynamic>? ?? [];
  // 批量转换为RecipeModel对象
  recipeList = rawList
      .map((item) => RecipeModel.fromJson(item as Map<String, dynamic>))
      .toList();
  
  // 触发页面重建,让GridView拿到最新数据
  if (mounted) setState(() {});
  print("成功解析${recipeList.length}条食谱数据");
}

@override
void initState() {
  super.initState();
  getRecipeData();
}

注意事项

  • 调用setState前判断mounted状态,避免页面已经销毁后触发状态更新的异常
  • 从Map中取嵌套字段时做明确的类型转换和空值兜底,降低JSON结构变动带来的运行时错误
  • 后续给GridView配置数据源时,直接使用成员变量recipeList作为itemCount的计算依据,itemBuilder中通过索引取出对应RecipeModel对象渲染即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 01:54:04