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

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,
          ),
        ],
      ),
    );
  }
}

额外说明

  1. 原来的SortbyNumber和SortbyAlphabet函数可以直接删除,现在所有排序逻辑都在状态内处理
  2. _loadData仅在组件初始化时调用一次,避免重复读取本地文件
  3. 每次排序都基于原始数据生成新列表,防止修改原始数据导致排序混乱
  4. setState()会触发build方法重新执行,ListView自动展示排序后的新数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 00:18:22