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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 14:32:42