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

iOS UICollectionViewDiffableDataSource功能迁移到Flutter的实现咨询

实现动态分组折叠列表的方案

核心逻辑是将硬编码的面板、子项改为遍历数据源动态生成,同时用状态列表单独控制每一个分组的展开状态,适配可变的数据源需求。

1. 定义匹配的Dart数据模型

对应iOS端的结构体,先定义Dart侧的数据结构:

class StudentItem {
  final String name;
  final String favColor;
  StudentItem({required this.name, required this.favColor});
}

class ClassItem {
  final String year;
  final List<StudentItem> students;
  ClassItem({required this.year, required this.students});
}

2. 声明数据源与展开状态存储

原来的单个_expanded变量只能控制一个面板的展开状态,多分组场景下需要用列表存储每个分组的展开状态,和数据源长度一一对应:

// 可动态更新的分组数据源
List<ClassItem> biologyClass = [
  ClassItem(
    year: "2021",
    students: [
      StudentItem(name: "Michael Pearson", favColor: "blue"),
      StudentItem(name: "Pearson Michael", favColor: "green"),
    ],
  ),
  ClassItem(
    year: "2020",
    students: [
      StudentItem(name: "Steve Pearson", favColor: "blue"),
      StudentItem(name: "Steve Michael", favColor: "green"),
      StudentItem(name: "Pearson Steve", favColor: "red"),
    ],
  ),
];
// 存储每个分组的展开状态,初始默认全部折叠
late List<bool> _expandedList;

@override
void initState() {
  super.initState();
  _expandedList = List.filled(biologyClass.length, false);
}

3. 动态构建列表组件

通过遍历数据源生成对应的ExpansionPanel和子级ListTile,无需硬编码每个条目:

@override
Widget build(BuildContext context) {
  // 外层加SingleChildScrollView避免内容溢出
  return SingleChildScrollView(
    child: ExpansionPanelList(
      dividerColor: Colors.grey,
      expansionCallback: (panelIndex, isExpanded) {
        setState(() {
          // 仅修改当前点击分组的展开状态
          _expandedList[panelIndex] = !_expandedList[panelIndex];
        });
      },
      // 遍历分组数据源生成ExpansionPanel
      children: biologyClass.asMap().entries.map((entry) {
        int groupIndex = entry.key;
        ClassItem groupData = entry.value;
        return ExpansionPanel(
          // 加唯一key避免Duplicate Keys报错
          key: ValueKey(groupData.year),
          headerBuilder: (context, isExpanded) {
            return ListTile(
              title: Text(
                groupData.year,
                style: const TextStyle(color: Colors.black),
              ),
            );
          },
          body: Column(
            // 遍历当前分组的学生列表生成子项ListTile
            children: groupData.students.map((student) {
              return ListTile(
                key: ValueKey(student.name),
                title: Text(
                  student.name,
                  style: const TextStyle(color: Colors.black),
                ),
                // 可根据favColor扩展更多UI逻辑
              );
            }).toList(),
          ),
          isExpanded: _expandedList[groupIndex],
          canTapOnHeader: true,
        );
      }).toList(),
    ),
  );
}

后续如果需要更新数据源,只要修改biologyClass的内容、同步调整_expandedList的长度后调用setState即可自动刷新UI,效果和iOS端的UICollectionViewDiffableDataSource动态刷新一致。给每个组件添加唯一ValueKey可以避免重复渲染导致的报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 03:54:03