Flutter中如何根据用户选择排序列表并更新UI
解决方案
核心问题是你没把数据存在状态里,每次排序都重复读取JSON,且点击按钮后没触发UI刷新。直接调整状态管理逻辑即可,不用每次都调用Future:
关键改动点
- 在State类里维护两个列表:原始数据列表(仅加载一次)、当前展示列表(用于排序后更新UI)
- 初始化时一次性读取JSON数据,之后排序都基于原始数据在内存中操作,避免重复IO
- 点击排序按钮时,对原始数据排序后更新展示列表,调用
setState()触发UI刷新
修改后的完整代码
class _SawnawkScreenState extends State<SawnawkScreen> { List<SawnAwkModel>? _originalList; List<SawnAwkModel>? _displayList; @override void initState() { super.initState(); _loadData(); } // 一次性加载本地JSON数据 Future<void> _loadData() async { final jsondata = await rootBundle.loadString('assets/data/sawnawk_data.json'); final list = json.decode(jsondata) as List<dynamic>; setState(() { _originalList = list.map((e) => SawnAwkModel.fromJson(e)).toList(); // 初始默认按数字排序 _displayList = List.from(_originalList!); }); } // 按字母排序 void _sortByAlphabet() { if (_originalList == null) return; final sortedList = List.from(_originalList!); sortedList.sort((a, b) { return a.titleFalam.toLowerCase().compareTo(b.titleFalam.toLowerCase()); }); setState(() { _displayList = sortedList; }); } // 按数字排序(假设id为数字类型,直接比较即可) void _sortByNumber() { if (_originalList == null) return; final sortedList = List.from(_originalList!); sortedList.sort((a, b) { return a.id!.compareTo(b.id!); }); setState(() { _displayList = sortedList; }); } @override Widget build(BuildContext context) { return Scaffold( body: _displayList == null ? const Center(child: CircularProgressIndicator()) : ListView.builder( itemCount: _displayList!.length, itemBuilder: (context, index) { return SawnawkCardWidget( id: _displayList![index].id!, ); }, ), floatingActionButton: SpeedDial( children: [ SpeedDialChild( child: const Icon(Icons.sort_by_alpha_outlined), backgroundColor: Colors.white, label: 'Sort by alphabet', onTap: _sortByAlphabet, ), SpeedDialChild( child: const Icon(Icons.sort_by_number), backgroundColor: Colors.white, label: 'Sort by number', onTap: _sortByNumber, ), ], ), ); } }
额外说明
- 原来的
SortbyNumber和SortbyAlphabet函数可以直接删除,现在所有排序逻辑都在状态内处理 _loadData仅在组件初始化时调用一次,避免重复读取本地文件- 每次排序都基于原始数据生成新列表,防止修改原始数据导致排序混乱
setState()会触发build方法重新执行,ListView自动展示排序后的新数据
内容的提问来源于stack exchange,提问作者aasenomad
相关产品推荐
相关产品推荐

