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

如何在Flutter中将含数组键的JSON数组转为ExpansionTile列表

解决JSON转换为ExpansionTile列表的问题

原代码存在的核心问题

  • 变量名不匹配:解析后得到tags,但循环时用了未定义的bookList
  • 类型不安全:直接使用List<dynamic>,未转换成具体实体类,导致属性访问报错
  • 拼写错误:chrildren应为children,<Widgets>应为<Widget>
  • 错误的列表项展示:直接将j(OwnerHistory对象)传给Text,会打印对象实例而非具体字段
  • 空值处理不当:List.from(tagsJson) : null会导致类型不匹配,null无法赋值给List<dynamic>

完整解决方案

第一步:创建数据模型类

定义对应JSON结构的实体类,保证类型安全:

class Book {
  final String bookName;
  final List<OwnerHistory> ownerHistory;

  Book({required this.bookName, required this.ownerHistory});

  // 手动实现fromJson方法(也可使用json_serializable简化)
  factory Book.fromJson(Map<String, dynamic> json) {
    var ownerHistoryList = json['Ownerhistory'] as List;
    List<OwnerHistory> owners = ownerHistoryList
        .map((ownerJson) => OwnerHistory.fromJson(ownerJson))
        .toList();

    return Book(
      bookName: json['bookName'],
      ownerHistory: owners,
    );
  }
}

class OwnerHistory {
  final String name;
  final String address;

  OwnerHistory({required this.name, required this.address});

  factory OwnerHistory.fromJson(Map<String, dynamic> json) {
    return OwnerHistory(
      name: json['name'],
      address: json['address'],
    );
  }
}

第二步:修正JSON解析逻辑

将JSON字符串转换成List<Book>,同时处理空值和解析异常:

final jsonStringData = ref.watch(responseProvider);
List<Book> bookList = [];

if (jsonStringData != null && jsonStringData.isNotEmpty) {
  try {
    var decodedList = jsonDecode(jsonStringData) as List;
    bookList = decodedList.map((item) => Book.fromJson(item)).toList();
  } catch (e) {
    // 处理解析错误,比如打印日志或提示用户
    print('JSON解析失败: $e');
  }
}

第三步:修正ExpansionTile列表构建

修正拼写错误,正确遍历列表并展示字段:

return Column(
  children: [
    for (var book in bookList)
      ExpansionTile(
        title: Text(book.bookName),
        children: [
          for (var owner in book.ownerHistory)
            ListTile(
              title: Text(owner.name),
              subtitle: Text(owner.address), // 额外展示地址信息
            )
        ],
      )
  ],
);

完整代码整合

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

class Book {
  final String bookName;
  final List<OwnerHistory> ownerHistory;

  Book({required this.bookName, required this.ownerHistory});

  factory Book.fromJson(Map<String, dynamic> json) {
    var ownerHistoryList = json['Ownerhistory'] as List;
    List<OwnerHistory> owners = ownerHistoryList
        .map((ownerJson) => OwnerHistory.fromJson(ownerJson))
        .toList();

    return Book(
      bookName: json['bookName'],
      ownerHistory: owners,
    );
  }
}

class OwnerHistory {
  final String name;
  final String address;

  OwnerHistory({required this.name, required this.address});

  factory OwnerHistory.fromJson(Map<String, dynamic> json) {
    return OwnerHistory(
      name: json['name'],
      address: json['address'],
    );
  }
}

class BookScreen extends ConsumerWidget {
  const BookScreen({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final jsonStringData = ref.watch(responseProvider);
    List<Book> bookList = [];

    if (jsonStringData != null && jsonStringData.isNotEmpty) {
      try {
        var decodedList = jsonDecode(jsonStringData) as List;
        bookList = decodedList.map((item) => Book.fromJson(item)).toList();
      } catch (e) {
        print('JSON解析失败: $e');
      }
    }

    return Column(
      children: [
        for (var book in bookList)
          ExpansionTile(
            title: Text(book.bookName),
            children: [
              for (var owner in book.ownerHistory)
                ListTile(
                  title: Text(owner.name),
                  subtitle: Text(owner.address),
                )
            ],
          )
      ],
    );
  }
}

// 假设responseProvider是你定义的Provider
final responseProvider = StateProvider<String?>((ref) => null);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 06:34:51