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

Flutter解析API响应创建Game对象时遭遇List类型不匹配异常的解决方案咨询

Flutter JSON解析错误:type 'List' is not a subtype of type 'List<Map<String, dynamic>>'

问题背景

我从API获取了如下响应文本,尝试创建新的Game对象时触发了类型不匹配的错误:

API响应内容:

{success: true, games: [{game_id: 3, game_gide: {0: b, 1: , 2: , 3: a, 11: b, 14: e}, game_cells: [3,8,23,18,2,7,17,22,1,6,16,21], game_questions: [{title: question 2 h, answer: abcde, isTrue: false}, {title: question 1 h, answer: xxxxx, isTrue: false}]}

错误信息:

Unhandled Exception: type 'List' is not a subtype of type 'List<Map<String, dynamic>>'

Game与Question类代码:

class Game {
  String gameId;
  String gameLevel;
  List<int> gameCells;
  List<Question> gameQuestions;
  Game({
    this.gameId,
    this.gameLevel,
    this.gameCells,
    this.gameQuestions,
  });
  static fromJson(Map<String, dynamic> parsedJson){
    print(parsedJson['game_vertical_questions']);
    return Game(
      gameId: parsedJson['game_id'],
      gameLevel: parsedJson['game_level'],
      gameCells: (jsonDecode(parsedJson['game_cells']) as List<dynamic>).cast<int>(),
      gameQuestions : Question.listFromJson(parsedJson['game_questions']),
    );
  }
}

class Question {
  String title;
  String answer;
  bool isTrue;
  Question({ this.title, this.answer, this.isTrue});
  static listFromJson(List<Map<String, dynamic>> list) {
    List<Question> questions = [];
    for (var value in list) {
      questions.add(Question.fromJson(value));
    }
    return questions;
  }
  static fromJson(Map<String, dynamic> parsedJson){
    return Question(
      title: parsedJson["title"],
      answer: parsedJson["answer"],
      isTrue: parsedJson["isTrue"]
    );
  }
}

触发错误的代码:

var jsonData = json.decode(response.body);
var res = jsonData["games"];
for (var g in res){
  //print(g);
  Game game = Game.fromJson(g);
  setState(() {
    gamesList.add(game);
  });
}

错误指向Game类中的这一行:

gameQuestions : Question.listFromJson(parsedJson['game_questions']),

错误原因分析

这个错误的核心是类型不匹配:你的Question.listFromJson方法要求传入List<Map<String, dynamic>>类型的参数,但parsedJson['game_questions']实际是List<dynamic>类型(json.decode返回的集合默认是dynamic泛型),Dart无法自动将List<dynamic>隐式转换为List<Map<String, dynamic>>,因此抛出了类型转换异常。

另外你提供的API响应存在JSON格式不规范问题:所有键和字符串值都没有用双引号包裹(比如success应该是"success",b应该是"b"),虽然Dart的json.decode可能兼容部分不规范JSON,但这可能导致解析后的结构和预期不一致,也是潜在隐患。


解决办法

1. 修改Question.listFromJson的参数类型

将方法参数从List<Map<String, dynamic>>改为List<dynamic>,并在内部显式转换每个元素类型:

class Question {
  // ... 其他代码不变
  static listFromJson(List<dynamic> list) {
    List<Question> questions = [];
    for (var value in list) {
      // 显式转换每个元素为Map<String, dynamic>
      questions.add(Question.fromJson(value as Map<String, dynamic>));
    }
    return questions;
  }
  // ... 其他代码不变
}

2. 增加空值判断与类型校验

在Game.fromJson中对game_questions做空值判断,同时修正字段映射错误(API里是game_gide,但你代码里用的是game_level):

static fromJson(Map<String, dynamic> parsedJson){
  return Game(
    gameId: parsedJson['game_id'].toString(), // 确保转为String类型
    gameLevel: parsedJson['game_gide']?.toString(), // 修正字段名不匹配问题
    gameCells: (parsedJson['game_cells'] as List<dynamic>).cast<int>(), // 无需jsonDecode,game_cells已是数组
    gameQuestions: parsedJson['game_questions'] != null 
        ? Question.listFromJson(parsedJson['game_questions'] as List<dynamic>)
        : [], // 空数组作为默认值避免空指针
  );
}

3. 修复API响应的JSON格式(如果可控)

建议让API返回标准JSON格式,所有键和字符串值用双引号包裹,示例如下:

{
  "success": true,
  "games": [
    {
      "game_id": 3,
      "game_gide": {"0": "b", "1": "", "2": "", "3": "a", "11": "b", "14": "e"},
      "game_cells": [3,8,23,18,2,7,17,22,1,6,16,21],
      "game_questions": [
        {"title": "question 2 h", "answer": "abcde", "isTrue": false},
        {"title": "question 1 h", "answer": "xxxxx", "isTrue": false}
      ]
    }
  ]
}

标准格式能避免很多解析时的意外问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 21:37:43