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

Flutter解析复杂多层JSON响应并转Dart模型显示问题

解决Flutter嵌套数组解析与ListView.builder失效问题

一、确认Dart模型类的正确性

在线JSON转Dart工具生成的代码可能存在嵌套数组解析错误,你需要确保每个嵌套层级的fromJson方法正确处理List类型。以下是适配你数据结构的示例模型:

class ActivityResponse {
  final List<ActivityFieldValue> activityFieldValueList;

  ActivityResponse({required this.activityFieldValueList});

  factory ActivityResponse.fromJson(Map<String, dynamic> json) {
    return ActivityResponse(
      activityFieldValueList: List<ActivityFieldValue>.from(
        json['activityFieldValueList'].map((x) => ActivityFieldValue.fromJson(x)),
      ),
    );
  }
}

class ActivityFieldValue {
  final AttributeType attributeType;

  ActivityFieldValue({required this.attributeType});

  factory ActivityFieldValue.fromJson(Map<String, dynamic> json) {
    return ActivityFieldValue(
      attributeType: AttributeType.fromJson(json['attributeType']),
    );
  }
}

class AttributeType {
  final List<LookupValues> lookupValues;

  AttributeType({required this.lookupValues});

  factory AttributeType.fromJson(Map<String, dynamic> json) {
    return AttributeType(
      lookupValues: List<LookupValues>.from(
        json['lookupValues'].map((x) => LookupValues.fromJson(x)),
      ),
    );
  }
}

class LookupValues {
  final String lookupValue;

  LookupValues({required this.lookupValue});

  factory LookupValues.fromJson(Map<String, dynamic> json) {
    return LookupValues(
      lookupValue: json['lookupValue'] ?? '', // 增加空值处理避免崩溃
    );
  }
}

二、API响应解析

使用http包发起请求并解析数据,确保异常处理逻辑完善:

import 'dart:convert';
import 'package:http/http.dart' as http;

Future<ActivityResponse> fetchActivityData() async {
  final response = await http.get(Uri.parse('你的API接口地址'));
  
  if (response.statusCode == 200) {
    return ActivityResponse.fromJson(jsonDecode(response.body));
  } else {
    throw Exception('请求失败,状态码:${response.statusCode}');
  }
}

三、修复ListView.builder不工作问题

常见失效原因是列表长度不匹配或未正确遍历嵌套层级,提供两种展示方案:

方案1:扁平化展示所有lookupValue

将嵌套数组中的所有lookupValue收集到一个列表,直接展示:

class ActivityScreen extends StatefulWidget {
  @override
  _ActivityScreenState createState() => _ActivityScreenState();
}

class _ActivityScreenState extends State<ActivityScreen> {
  late Future<ActivityResponse> _futureData;

  @override
  void initState() {
    super.initState();
    _futureData = fetchActivityData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('嵌套数据展示')),
      body: FutureBuilder<ActivityResponse>(
        future: _futureData,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            // 收集所有lookupValue
            final allLookupValues = <String>[];
            for (final field in snapshot.data!.activityFieldValueList) {
              for (final lookup in field.attributeType.lookupValues) {
                allLookupValues.add(lookup.lookupValue);
              }
            }

            return ListView.builder(
              itemCount: allLookupValues.length, // 匹配列表长度
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text(allLookupValues[index]),
                );
              },
            );
          } else if (snapshot.hasError) {
            return Center(child: Text('错误:${snapshot.error}'));
          }
          // 加载中状态
          return const Center(child: CircularProgressIndicator());
        },
      ),
    );
  }
}

方案2:嵌套展开展示

保留层级结构,用ExpansionTile展示每个字段下的所有lookupValue:

// 替换FutureBuilder中的返回部分
if (snapshot.hasData) {
  return ListView.builder(
    itemCount: snapshot.data!.activityFieldValueList.length,
    itemBuilder: (context, index) {
      final field = snapshot.data!.activityFieldValueList[index];
      return ExpansionTile(
        title: Text('字段 ${index + 1}'),
        children: field.attributeType.lookupValues.map((lookup) {
          return ListTile(title: Text(lookup.lookupValue));
        }).toList(),
      );
    },
  );
}

常见排查点

  • 检查模型类中lookupValues是否被定义为List<LookupValues>,而非单个对象
  • 确认ListView.builder的itemCount与数据源长度完全匹配
  • 给lookupValue增加空值处理,避免API返回null导致崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 21:22:51