Flutter本地JSON解析报错:List无法转为Map,求获取菜品名称列表
解决Flutter解析JSON时的类型错误并生成菜品名称列表
我来帮你搞定这个问题!首先咱们先拆解你遇到的问题,然后一步步修正代码:
错误根源分析
你碰到的type 'List' is not a subtype of type 'Map'错误,核心原因是你的JSON文件根结构是一个数组(List),但你强行把解析结果赋值给了Map类型的变量,这就导致了类型不匹配。
修正步骤与代码调整
1. 修正JSON解析的类型匹配
首先把解析后的变量类型从Map改成List,因为你的JSON根是数组结构:
// 原错误代码:Map myData = json.decode(snapshot.data); List myData = json.decode(snapshot.data);
2. 正确收集所有菜品名称
你的JSON结构是多层嵌套的:根数组 → 每个元素包含table_menu_list数组 → 每个菜单包含category_dishes数组 → 每个菜品包含dish_name。我们需要逐层遍历,把所有菜品名称收集到一个列表里:
可以用简洁的链式调用方式:
List<String> allDishNames = myData .expand((item) => item['table_menu_list'] as List) // 展开所有table_menu_list .expand((menu) => menu['category_dishes'] as List) // 展开所有category_dishes .map((dish) => dish['dish_name'] as String) // 提取每个菜品的名称 .toList();
也可以用嵌套循环的方式(更直观):
List<String> allDishNames = []; for (var rootItem in myData) { var tableMenuList = rootItem['table_menu_list'] as List; for (var menuItem in tableMenuList) { var categoryDishes = menuItem['category_dishes'] as List; for (var dish in categoryDishes) { allDishNames.add(dish['dish_name']); } } }
3. 重构ListView生成逻辑
之前的代码里用同一个index去取所有层级的元素是错误的(比如myData[index]['table_menu_list'][index]),因为每个层级的数组长度不一定一致。现在用收集好的allDishNames来生成列表:
return ListView.builder( itemBuilder: (BuildContext context, index) { return Card( child: ListTile( title: Text(allDishNames[index]), ), ); }, itemCount: allDishNames.length, );
完整修正后的代码
import 'dart:convert'; import 'package:flutter/material.dart'; import 'JsonParsing.dart'; class Home extends StatefulWidget { @override HomeState createState() => new HomeState(); } class HomeState extends State<Home> { List data; @override Widget build(BuildContext context) { return new Scaffold( appBar: AppBar( title: Text("Some App"), ), body: Container( child: Center( child: FutureBuilder( future: DefaultAssetBundle.of(context).loadString('jsons/data.json'), builder: (context, snapshot) { if (!snapshot.hasData) { return CircularProgressIndicator(); } // 修正:JSON根是List,用List类型接收 List myData = json.decode(snapshot.data); // 收集所有菜品名称 List<String> allDishNames = myData .expand((item) => item['table_menu_list'] as List) .expand((menu) => menu['category_dishes'] as List) .map((dish) => dish['dish_name'] as String) .toList(); print("总菜品数量:${allDishNames.length}"); return ListView.builder( itemBuilder: (BuildContext context, index) { return Card( child: ListTile( title: Text(allDishNames[index]), )); }, itemCount: allDishNames.length, ); }, ), ), ), ); } }
额外提示
如果你想继续使用User类来解析数据,需要确保User类的结构和JSON根数组里的单个元素完全匹配,然后把解析代码改成:
List<User> users = myData.map((jsonItem) => User.fromJson(jsonItem)).toList();
之后再从users列表里逐层遍历收集菜品名称即可。
内容的提问来源于stack exchange,提问作者Flutture
相关产品推荐
相关产品推荐

