Flutter中筛选指定类型JSON数据并在ListView.builder中使用
Flutter动态筛选JSON数据并在ListView.builder展示
步骤1:定义数据模型类
先把JSON结构映射成Dart实体类,方便后续操作。假设你的JSON数据结构如下:
[ {"id": 1, "name": "帆布包", "type": "bag"}, {"id": 2, "name": "运动鞋", "type": "shoe"}, {"id": 3, "name": "双肩包", "type": "bag"} ]
对应的Dart实体类:
class Item { final int id; final String name; final String type; Item({required this.id, required this.name, required this.type}); // 从JSON转成Item对象的工厂方法 factory Item.fromJson(Map<String, dynamic> json) { return Item( id: json['id'], name: json['name'], type: json['type'], ); } }
步骤2:加载并解析JSON数据
不管是本地assets文件还是网络接口返回的JSON,先把数据解析成List<Item>格式。这里以本地assets为例(记得先在pubspec.yaml里配置assets路径):
import 'dart:convert'; import 'package:flutter/services.dart'; Future<List<Item>> loadItems() async { // 加载本地JSON文件 final String response = await rootBundle.loadString('assets/items.json'); // 解析成List<dynamic> final List<dynamic> data = json.decode(response); // 转成Item列表 return data.map((json) => Item.fromJson(json)).toList(); }
如果是网络请求,把rootBundle部分换成http请求即可:
import 'package:http/http.dart' as http; Future<List<Item>> loadItems() async { final response = await http.get(Uri.parse('https://your-api-url/items')); if (response.statusCode == 200) { final List<dynamic> data = json.decode(response.body); return data.map((json) => Item.fromJson(json)).toList(); } else { throw Exception('加载数据失败'); } }
步骤3:实现动态筛选逻辑
把筛选条件做成可动态修改的变量(比如从下拉框、按钮等控件获取),然后用where方法过滤原始列表:
// 存储当前筛选类型,可动态修改 String _currentFilterType = 'bag'; // 筛选后的列表 List<Item> filteredItems = allItems.where((item) => item.type == _currentFilterType).toList();
步骤4:用ListView.builder展示筛选结果
结合FutureBuilder处理异步数据加载,再用ListView.builder渲染筛选后的列表:
class FilteredItemList extends StatefulWidget { final String initialFilterType; // 支持从外部传入初始筛选条件 const FilteredItemList({super.key, required this.initialFilterType}); @override State<FilteredItemList> createState() => _FilteredItemListState(); } class _FilteredItemListState extends State<FilteredItemList> { late Future<List<Item>> _futureItems; late String _currentFilterType; @override void initState() { super.initState(); _currentFilterType = widget.initialFilterType; _futureItems = loadItems(); } // 修改筛选条件的方法,可通过外部控件触发 void updateFilter(String newType) { setState(() { _currentFilterType = newType; }); } @override Widget build(BuildContext context) { return Column( children: [ // 示例:用下拉框动态切换筛选条件 DropdownButton<String>( value: _currentFilterType, items: const [ DropdownMenuItem(value: 'bag', child: Text('包类')), DropdownMenuItem(value: 'shoe', child: Text('鞋类')), ], onChanged: (value) { if (value != null) updateFilter(value); }, ), Expanded( child: FutureBuilder<List<Item>>( future: _futureItems, builder: (context, snapshot) { if (snapshot.hasData) { final allItems = snapshot.data!; // 实时筛选数据 final filteredItems = allItems.where((item) => item.type == _currentFilterType).toList(); return ListView.builder( itemCount: filteredItems.length, itemBuilder: (context, index) { final item = filteredItems[index]; return ListTile( leading: CircleAvatar(child: Text(item.id.toString())), title: Text(item.name), subtitle: Text('类型: ${item.type}'), ); }, ); } else if (snapshot.hasError) { return Center(child: Text('加载失败: ${snapshot.error}')); } // 加载中状态 return const Center(child: CircularProgressIndicator()); }, ), ), ], ); } }
内容的提问来源于stack exchange,提问作者alex
相关产品推荐
相关产品推荐

