Flutter应用无法加载JSON文件问题求助
问题分析与解决方案
错误根源
报错type 'Null' is not a subtype of type 'List'主要来自三个核心问题:
- FutureBuilder状态未正确处理:直接访问
snapshot.data.toString(),当快照处于加载中或加载失败时,snapshot.data为null,转字符串后解码结果是null,强制赋值给List类型变量触发类型错误。 - JSON解码无类型校验:默认假设解码结果一定是
List,但实际可能因文件不存在、格式错误返回null或其他类型。 - 主题匹配遗漏:新增语言的主题未在
setasset()的判断分支中,导致assettoload可能未被赋值,间接引发后续加载、解码异常。
修复代码
class Json extends StatelessWidget { final String topicname; late String assettoload; Json(this.topicname); setasset() { // 用switch替代冗长if-else,后续新增主题更易维护 switch(topicname) { case "farben": assettoload = "assets/lerndateien/farben.json"; break; case "Fragewörter": assettoload = "assets/lerndateien/fragewoerter.json"; break; case "Begrüßungen": assettoload = "assets/lerndateien/saetze.json"; break; case "Konsonanten": assettoload = "assets/lerndateien/konsonanten.json"; break; case "Selbstlaute": assettoload = "assets/lerndateien/selbstlaute.json"; break; case "Wochentage": assettoload = "assets/lerndateien/wochentage.json"; break; case "Zeitangaben": assettoload = "assets/lerndateien/zeitangaben.json"; break; case "Einkaufen": assettoload = "assets/lerndateien/einkaufen.json"; break; case "Konversation": assettoload = "assets/lerndateien/konversation.json"; break; case "Richtungen": assettoload = "assets/lerndateien/richtungsangaben.json"; break; case "Über mich": assettoload = "assets/lerndateien/uebermich.json"; break; case "Wegweisung": assettoload = "assets/lerndateien/wegweisungen.json"; break; case "Lebensmittel": assettoload = "assets/lerndateien/lebensmittel.json"; break; case "Tiere": assettoload = "assets/lerndateien/tiere.json"; break; // 新增默认分支,避免assettoload未初始化 default: // 替换为新增语言主题的对应JSON路径,或设置错误提示文件 assettoload = "assets/lerndateien/default.json"; break; } } @override Widget build(BuildContext context) { setasset(); return FutureBuilder<String>( // 指定泛型为String,提升类型安全 future: DefaultAssetBundle.of(context).loadString(assettoload, cache: false), builder: (context, snapshot) { // 处理加载中状态 if (snapshot.connectionState == ConnectionState.waiting) { return Scaffold( body: Row( children: [ BackButton(), Center(child: Text("Lädt...")), ], ), ); } // 处理加载错误 if (snapshot.hasError) { return Scaffold( body: Row( children: [ BackButton(), Center(child: Text("Fehler beim Laden: ${snapshot.error}")), ], ), ); } // 确保数据存在再解码 if (!snapshot.hasData || snapshot.data == null) { return Scaffold( body: Row( children: [ BackButton(), Center(child: Text("Keine Daten verfügbar")), ], ), ); } // 解码后校验类型,避免强制类型转换错误 final decodedData = json.decode(snapshot.data!); if (decodedData is! List) { return Scaffold( body: Row( children: [ BackButton(), Center(child: Text("Ungültige JSON-Struktur")), ], ), ); } // 数据正常,跳转目标页面 return quizpage(mydata: decodedData); }, ); } }
关键修复说明
- 完善状态处理:依次判断加载中、错误、无数据状态,彻底避免访问null数据。
- 类型安全校验:解码后明确判断结果是否为
List,防止类型不匹配报错。 - 默认分支兜底:确保
assettoload始终被赋值,解决新增主题未匹配导致的初始化问题。 - 代码结构优化:用
switch简化分支逻辑,后续新增语言主题更易扩展。
内容的提问来源于stack exchange,提问作者Molgolaiven
相关产品推荐
相关产品推荐

