可展开列表 - Flutter适配OpenHarmony PC
·
#
案例概述
本案例展示如何使用 ExpansionTile 创建可展开/折叠的列表。可展开列表是组织分类信息的有效方式,广泛应用于菜单、常见问题、设置选项等场景。通过展开和折叠,用户可以专注于感兴趣的内容,减少屏幕混乱。ExpansionTile 提供了内置的展开/折叠动画和状态管理,使实现变得简单。
可展开列表需要管理每个项的展开状态、支持嵌套列表、处理动态加载等。此外,还应考虑全选/取消全选、搜索过滤、键盘导航等高级功能。
核心概念
1. ExpansionTile
- 可展开的列表项;
- 支持标题和子内容;
- 支持展开/折叠动画。
2. 展开状态
initiallyExpanded:初始是否展开;onExpansionChanged:展开状态改变回调;- 支持多个独立的展开/折叠状态。
3. 嵌套列表
- ExpansionTile 内部可包含 ListView;
- 支持多层嵌套;
- 支持动态加载子项。
代码详解
1. 基础展开列表
ExpansionTile(
title: Text('分类'),
children: [
ListTile(title: Text('项目1')),
ListTile(title: Text('项目2')),
],
)
2. 展开状态管理
Map<int, bool> _expandedStates = {};
ExpansionTile(
initiallyExpanded: _expandedStates[index] ?? false,
onExpansionChanged: (expanded) {
setState(() => _expandedStates[index] = expanded);
},
title: Text('分类'),
children: [...],
)
3. 嵌套列表
ExpansionTile(
title: Text('分类'),
children: [
ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(title: Text(items[index]));
},
),
],
)
高级话题:展开列表的企业级应用
1. 动态加载子项
ExpansionTile(
title: Text('分类'),
onExpansionChanged: (expanded) {
if (expanded && !_loadedCategories.contains(index)) {
_loadSubItems(index);
}
},
children: [...],
)
2. 展开列表搜索
List<Map<String, dynamic>> get _filteredCategories {
return _categories.where((cat) {
return cat['title'].toLowerCase().contains(_searchQuery.toLowerCase()) ||
cat['items'].any((item) => item.toLowerCase().contains(_searchQuery.toLowerCase()));
}).toList();
}
3. 展开列表排序
void _sortCategories(String sortBy) {
setState(() {
_categories.sort((a, b) {
if (sortBy == 'name') {
return a['title'].compareTo(b['title']);
}
return a['items'].length.compareTo(b['items'].length);
});
});
}
4. 展开列表的全选/取消全选
void _expandAll() {
setState(() {
_expandedStates.updateAll((key, value) => true);
});
}
void _collapseAll() {
setState(() {
_expandedStates.updateAll((key, value) => false);
});
}
5. 展开列表的计数显示
ExpansionTile(
title: Row(
children: [
Text('分类'),
SizedBox(width: 8),
Badge(label: Text(items.length.toString())),
],
),
children: [...],
)
6. 展开列表的操作菜单
ExpansionTile(
trailing: PopupMenuButton<String>(
itemBuilder: (context) => [
PopupMenuItem(value: 'edit', child: Text('编辑')),
PopupMenuItem(value: 'delete', child: Text('删除')),
],
),
title: Text('分类'),
children: [...],
)
7. 展开列表的键盘导航
Focus(
onKey: (node, event) {
if (event.isKeyPressed(LogicalKeyboardKey.enter)) {
setState(() => _expandedStates[index] = !_expandedStates[index]!);
return KeyEventResult.handled;
}
return KeyEventResult.ignored;
},
child: ExpansionTile(...),
)
8. 展开列表的无障碍支持
ExpansionTile(
title: Semantics(
label: '分类 ${index + 1}',
child: Text('分类'),
),
children: [...],
)
9. 展开列表的动画自定义
ExpansionTile(
title: Text('分类'),
collapsedBackgroundColor: Colors.grey.shade100,
backgroundColor: Colors.blue.shade50,
children: [...],
)
10. 展开列表的测试
test('展开列表展开', () {
expect(_expandedStates[0], false);
_toggleExpanded(0);
expect(_expandedStates[0], true);
});
通过这些企业级技巧,你可以构建出功能完整的展开列表系统。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)