在这里插入图片描述

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

案例概述

本案例展示如何使用 ExpansionTile + ListView 实现一个「可折叠的分组列表」。这种结构适合有天然分组属性的数据,例如按日期分组的任务、按状态分组的订单、按分类分组的设置项等。

页面结构上:

  • 最外层是一个 ListView
  • 每个分组是一个带卡片背景的 ExpansionTile
  • 展开后显示该分组下的若干 ListTile 子项;
  • 同样根据屏幕宽度调整水平内边距,以适配 PC/平板/手机。

核心概念

1. 分组数据结构

案例中使用一个简单的 Map<String, List<String>> 来描述分组:

  • key 表示分组名称,如“今天”、“本周”、“稍后”;
  • value 是该分组下的任务名称列表。

你在真实项目中可以将 value 换成自定义对象列表,只需在构建子项时读取对应字段即可。

2. ExpansionTile 折叠/展开

ExpansionTile 自带:

  • 带箭头的标题行;
  • 折叠/展开动画;
  • 将子组件包裹在可展开容器中的能力。

这样无需自己写动画逻辑,就能实现基础的展开/收起效果。

代码详解

1. 页面结构与数据准备

class GroupedListPage extends StatelessWidget {
  const GroupedListPage({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    final screenWidth = MediaQuery.of(context).size.width;
    final isTablet = screenWidth >= 600 && screenWidth < 1200;
    final isPC = screenWidth >= 1200;

    final horizontalPadding = isPC ? 48.0 : (isTablet ? 32.0 : 16.0);

    final groups = {
      '今天': ['任务 1', '任务 2', '任务 3'],
      '本周': ['任务 4', '任务 5'],
      '稍后': ['任务 6'],
    };
    // ...
  }
}

说明:

  • 同样使用 MediaQuery 判断设备类型并设置横向内边距;
  • groups Map 用来存储分组和任务列表,结构简单直观;
  • 在实际业务中,你可以使用日期、状态、类型等任意维度作为 key。

2. Scaffold 与 ListView

return Scaffold(
  appBar: AppBar(
    title: const Text('案例7:分组列表 - ExpansionTile + ListView'),
    centerTitle: isPC,
    elevation: 2,
  ),
  body: ListView(
    padding: EdgeInsets.symmetric(horizontal: horizontalPadding, vertical: 16),
    children: groups.entries.map((entry) {
      return Card(
        margin: const EdgeInsets.only(bottom: 12),
        child: ExpansionTile(
          // ...
        ),
      );
    }).toList(),
  ),
);

说明:

  • ListView 的 children 由 groups.entries.map 生成,每个 entry 对应一个分组卡片;
  • 使用 Card 包裹 ExpansionTile,让每个分组块有独立的视觉区域和阴影;
  • padding 控制列表整体与屏幕边缘的距离。

3. ExpansionTile 标题与子项

ExpansionTile(
  title: Text(
    entry.key,
    style: Theme.of(context).textTheme.titleMedium?.copyWith(
          fontWeight: FontWeight.bold,
        ),
  ),
  children: entry.value
      .map(
        (task) => ListTile(
          leading: const Icon(Icons.check_circle_outline),
          title: Text(task),
        ),
      )
      .toList(),
),

说明:

  • title 使用主题中的 titleMedium 样式并加粗,突出分组名称;
  • children 由当前分组的任务列表 .map 得到,每个任务对应一个 ListTile
  • leading 图标统一使用 Icons.check_circle_outline,象征任务项,可根据实际场景替换。

OpenHarmony PC 端适配要点

  1. 信息分层与折叠

    • 在 PC 端数据量往往更大,分组 + 折叠能够显著降低信息密度;
    • 用户只需展开关注的分组,其余保持折叠即可。
  2. 卡片式分组视觉

    • 每个分组外层用 Card 包裹,比单纯的分割线更有层次;
    • 在 PC 宽屏环境下,多块卡片纵向排列,阅读体验良好。
  3. 内边距控制

    • 通过 horizontalPadding 让内容远离屏幕边缘;
    • 不同设备宽度可使用不同的边距策略,与前面几个案例保持一致。

扩展建议

  • 在分组标题右侧增加数量统计,如“今天 (3)”;
  • 保存各分组的展开状态,在页面重新构建或返回时保持用户之前的展开/折叠选择;
  • 为任务项添加点击事件,打开任务详情或编辑弹窗;
  • 在 PC 端为分组或子项增加右键菜单,实现删除、标记完成等高级操作;
  • 使用自定义模型类型替代 String,为每个任务保存更多字段(优先级、截止时间、执行人等)。

深入理解:分组列表的信息架构

1. 为什么需要分组?

在数据量较大或数据具有天然分类属性时,平铺列表会显得混乱。分组的核心价值在于:

  • 降低认知负荷:用户不需要在一个长列表中寻找,而是先定位到某个分组,再在分组内查找;
  • 提升扫描效率:分组标题作为视觉锚点,让用户能快速跳过不关心的分组;
  • 组织信息:通过分组,应用能够清晰地表达数据的逻辑结构,例如时间维度(今天/本周/稍后)、状态维度(待处理/进行中/已完成)等。

2. ExpansionTile 的交互设计

ExpansionTile 提供的折叠/展开机制有几个优势:

  • 节省空间:用户可以只展开关心的分组,其他分组保持折叠状态,减少滚动距离;
  • 渐进式信息披露:用户可以先看到分组摘要(如数量统计),再决定是否展开查看详情;
  • 自动动画:展开/折叠时的平滑动画提升了交互的流畅感。

3. 分组维度的选择

分组可以按多种维度进行,不同维度适用于不同场景:

  • 时间维度:今天/本周/本月/更早,常见于任务管理、日程应用;
  • 状态维度:待处理/进行中/已完成,常见于工作流、项目管理;
  • 优先级维度:高/中/低,常见于任务列表、待办事项;
  • 分类维度:不同的业务分类,常见于电商、内容管理;
  • 字母维度:A-Z 首字母分组,常见于通讯录、词典。

选择合适的分组维度能够大幅提升用户体验。

4. PC 端分组列表的特殊考量

在 PC 宽屏上,分组列表可以进一步优化:

  • 默认展开策略:可以根据业务逻辑决定哪些分组默认展开(如"今天"分组),其他分组默认折叠;
  • 分组统计:在分组标题右侧显示该分组内的项目数量,帮助用户快速了解数据分布;
  • 快捷操作:为分组标题增加右键菜单或快捷按钮,实现"全部展开""全部折叠"等批量操作;
  • 记忆用户选择:保存用户的展开/折叠状态,下次打开页面时恢复用户的偏好。

5. 分组列表在业务系统中的应用

分组列表在各类应用中都很常见:

  • 任务管理:按时间分组(今天/本周/稍后)或按状态分组(待处理/进行中/已完成);
  • 消息中心:按类型分组(系统消息/用户消息/订单消息)或按时间分组(今天/昨天/更早);
  • 账单系统:按月份分组、按交易类型分组;
  • 文件管理:按文件类型分组、按修改时间分组。

通过合理使用分组,应用能够以更清晰、更高效的方式呈现大量数据。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐