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

Flutter嵌套JSON列表展示与搜索过滤实现方案咨询

嵌套JSON列表展示与搜索过滤解决方案

一、确认数据模型解析正确性

首先确保Dart模型类正确处理JSON的嵌套结构,以下是示例模型代码(根据你的实际JSON结构调整):

class Transaction {
  final String month;
  final List<Entry> entries;

  Transaction({required this.month, required this.entries});

  factory Transaction.fromJson(Map<String, dynamic> json) {
    final entriesList = json['entries'] as List;
    final entries = entriesList.map((e) => Entry.fromJson(e)).toList();
    return Transaction(month: json['month'], entries: entries);
  }
}

class Entry {
  final String name;
  final double amount;

  Entry({required this.name, required this.amount});

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

二、实现搜索过滤逻辑

使用StatefulWidget维护原始数据列表、过滤后列表,以及搜索输入控制器:

class TransactionScreen extends StatefulWidget {
  @override
  _TransactionScreenState createState() => _TransactionScreenState();
}

class _TransactionScreenState extends State<TransactionScreen> {
  final TextEditingController _searchController = TextEditingController();
  List<Transaction> _originalData = [];
  List<Transaction> _filteredData = [];

  @override
  void initState() {
    super.initState();
    _loadJsonData();
    _searchController.addListener(_filterData);
  }

  // 加载JSON数据(示例从assets读取,替换为你的数据源逻辑)
  void _loadJsonData() async {
    final jsonString = await rootBundle.loadString('assets/your_data.json');
    final jsonList = jsonDecode(jsonString) as List;
    _originalData = jsonList.map((e) => Transaction.fromJson(e)).toList();
    setState(() => _filteredData = List.from(_originalData));
  }

  // 搜索过滤核心逻辑
  void _filterData() {
    final query = _searchController.text.toLowerCase().trim();
    setState(() {
      if (query.isEmpty) {
        _filteredData = List.from(_originalData);
      } else {
        _filteredData = _originalData.where((item) {
          // 按月份匹配,可扩展为匹配条目内的字段(如entry.name)
          return item.month.toLowerCase().contains(query);
        }).toList();
      }
    });
  }

  @override
  void dispose() {
    _searchController.dispose();
    super.dispose();
  }

三、构建嵌套列表UI

结合搜索框与嵌套列表展示过滤后的数据,使用ExpansionTile实现折叠展开效果:

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('交易记录')),
      body: Column(
        children: [
          // 搜索输入框
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: TextField(
              controller: _searchController,
              decoration: InputDecoration(
                hintText: '搜索月份',
                prefixIcon: const Icon(Icons.search),
                border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)),
              ),
            ),
          ),
          // 嵌套列表展示
          Expanded(
            child: ListView.builder(
              itemCount: _filteredData.length,
              itemBuilder: (context, index) {
                final transaction = _filteredData[index];
                return ExpansionTile(
                  title: Text(transaction.month),
                  children: transaction.entries.map((entry) {
                    return ListTile(
                      title: Text(entry.name),
                      trailing: Text('\$${entry.amount.toStringAsFixed(2)}'),
                    );
                  }).toList(),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

四、常见问题排查

  • 嵌套数据解析失败:检查模型类的fromJson方法,确保递归处理了所有嵌套的子列表/对象,没有遗漏字段映射。
  • 搜索无响应:确认过滤逻辑中是否处理了大小写问题,且setState正确触发了UI更新;检查搜索控制器的监听是否在initState中正确注册。
  • 布局溢出:外层列表必须用Expanded包裹,避免因内容过长导致布局错误;嵌套子列表无需额外加Expanded,直接用map生成条目即可。

内容的提问来源于stack exchange,提问作者Ravindra S. Patil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 13:20:29