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

