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
相关产品推荐
相关产品推荐

