在这里插入图片描述

案例概述

本案例展示如何使用 Card + ListView 构建一个典型的「卡片式列表」页面,并针对手机、平板和 PC 端做简单的边距和排版适配。卡片列表在实际业务中非常常见,例如账单列表、订单列表、消息中心等。

我们在同一个页面中完成:

  • 基于内存数据生成多条记录;
  • 使用 ListView.builder 按需渲染卡片列表;
  • 每条记录用 Card + ListTile 呈现,包含图标、标题、副标题和金额;
  • 根据屏幕宽度调整整体内边距,让 PC 端显示更居中、留白更合理。

核心概念

1. ListView.builder 构建长列表

ListView.builder 只在需要显示某一项时才构建对应的 Widget,这对长列表来说更高效。即便本案例数据不多,也建议养成这一写法,便于扩展。

2. Card + ListTile 组合

  • Card 提供卡片式的视觉外观:阴影、圆角等;
  • ListTile 提供标准的行布局:左侧 leading、中间 title + subtitle、右侧 trailing
  • 两者配合,可以非常快速地搭建出整齐统一的卡片列表界面。

3. 响应式边距

通过 MediaQuery.of(context).size.width 判断当前是手机、平板还是 PC,然后调整:

  • horizontalPadding:水平内边距;
  • verticalPadding:垂直内边距;

使得:

  • 手机端内容基本占满宽度;
  • 平板端适当增加内边距,提升可读性;
  • PC 端加大左右留白,让卡片区域居中显示。

代码详解

1. 页面结构与数据准备

class CardListPage extends StatelessWidget {
  const CardListPage({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 verticalPadding = isPC ? 32.0 : (isTablet ? 24.0 : 16.0);

    final cards = List.generate(10, (index) {
      return {
        'title': '卡片 ${index + 1}',
        'subtitle': '这是一个 Card + ListView 的示例',
        'amount': (index + 1) * 120,
      };
    });
    // ...
  }
}

说明:

  • 根据 screenWidth 计算设备类型,并确定不同的内边距;
  • 使用 List.generate 生成示例数据,每条数据包含标题、副标题和金额;
  • 在真实项目中,你可以把这部分替换成接口返回的数据列表。

2. Scaffold 与 AppBar

return Scaffold(
  appBar: AppBar(
    title: const Text('案例6:卡片列表 - Card + ListView'),
    centerTitle: isPC,
    elevation: 2,
  ),
  body: ListView.builder(
    padding: EdgeInsets.symmetric(
      horizontal: horizontalPadding,
      vertical: verticalPadding,
    ),
    itemCount: cards.length,
    itemBuilder: (context, index) {
      final item = cards[index];
      // ...
    },
  ),
);

说明:

  • centerTitle: isPC 让 PC 端标题居中,更符合桌面风格;
  • ListView.builder 作为整个页面的内容区域,带有全局内边距;
  • 每一项的构建交给 itemBuilder 回调完成。

3. 单条卡片的构建

return Padding(
  padding: const EdgeInsets.only(bottom: 12),
  child: Card(
    elevation: isPC ? 1 : 3,
    child: ListTile(
      contentPadding: const EdgeInsets.all(16),
      leading: CircleAvatar(
        backgroundColor: Colors.indigo.shade100,
        child: Icon(Icons.credit_card, color: Colors.indigo.shade700),
      ),
      title: Text(
        item['title'].toString(),
        style: Theme.of(context).textTheme.titleMedium,
      ),
      subtitle: Text(item['subtitle'].toString()),
      trailing: Text(
        '\¥${item['amount']}',
        style: Theme.of(context).textTheme.titleMedium?.copyWith(
              fontWeight: FontWeight.bold,
              color: Colors.indigo,
            ),
      ),
    ),
  ),
);

说明:

  • 外层 Padding 为每个卡片之间添加 12 像素的垂直间距;
  • Card.elevation 在 PC 端稍弱,在移动端稍强,可以根据视觉需要继续微调;
  • CircleAvatar + Icon 用于展示与卡片内容相关的图标,增强识别度;
  • trailing 显示金额文本,并通过加粗与主题色突出显示。

OpenHarmony PC 端适配要点

  1. 宽屏上的内容居中

    • 使用较大的 horizontalPadding 将卡片区域压缩在中间,更符合桌面应用常见布局;
    • 如果屏幕特别宽,可以进一步用 ConstrainedBox 限制最大宽度,让列表保持合适的阅读宽度。
  2. 卡片阴影与层次感

    • PC 端用户通常在较亮的环境和大屏幕上使用应用,弱阴影、清晰边界可以提供更高级的视觉感受;
    • 可以结合深色模式,调整卡片背景和阴影颜色,确保在暗色主题下也足够清晰。
  3. 滚动体验

    • ListView 在 PC 端默认支持鼠标滚轮与触控板滚动;
    • 如果列表非常长,可以结合分页或“加载更多”机制来提升体验。

扩展建议

  • 在卡片右侧增加状态标签,如“已完成”、“待支付”等;
  • 支持点击卡片进入详情页面,在详情页展示更丰富的信息;
  • 在列表顶部增加筛选和排序控件,如按金额大小排序、按时间筛选等;
  • 为卡片增加 MouseRegion 悬停效果,在 PC 上提高交互反馈;
  • 结合网络请求,将示例数据替换为真实后端接口返回的账单或订单数据。

深入理解:卡片列表的设计原理

1. 为什么卡片是最常见的数据展示方式?

在现代应用设计中,卡片(Card)已经成为展示单条数据的"标准单元"。这不是偶然,而是有深层的设计原理支撑的:

  • 视觉分离:卡片通过阴影、边框、背景色等手段,将每条数据从周围环境中"隔离"出来,让用户能够清晰地识别出一个独立的信息单元;
  • 信息聚合:一张卡片可以同时展示多个相关字段(标题、副标题、金额、状态等),而不是像纯文本列表那样显得单调;
  • 交互友好:卡片的边界清晰,用户知道点击卡片的哪个区域会触发操作,降低了误操作风险;
  • 响应式友好:卡片的宽度可以灵活适应不同屏幕,从手机到 PC 都能保持良好的视觉效果。

2. 卡片设计的视觉层次

一张设计良好的卡片通常包含几个层次的信息:

  • 主要信息(如标题、金额):通常用更大的字号、更深的颜色或加粗来突出;
  • 次要信息(如副标题、描述):字号较小,颜色较浅,用于补充说明;
  • 操作区域(如按钮、图标):通常放在卡片的右侧或底部,便于用户快速定位;
  • 视觉装饰(如头像、图标、颜色块):增强卡片的识别度和美观度。

在本案例中,ListTile 已经为我们处理了大部分这些层次:leading(装饰)、title(主要)、subtitle(次要)、trailing(操作),让我们可以快速搭建出结构清晰的卡片。

3. 卡片列表 vs 其他列表形式

在数据展示时,你可能会面临几种选择:

  • 纯文本列表(简单 ListTile,无卡片包装):优点是代码简单、加载快,适合数据量极大的场景;缺点是视觉层次不够,难以突出重要信息。
  • 卡片列表(本案例):优点是视觉效果好、信息层次清晰;缺点是每条数据占用更多空间。
  • 表格列表(多列数据对齐):优点是可以同时展示多个字段便于对比;缺点是在移动端难以适配。
  • 网格卡片(多列排列):优点是充分利用宽屏空间;缺点是每条数据的详细信息展示受限。

因此,卡片列表是一种很好的平衡:既有卡片的视觉优势,又保持了列表的信息密度和易用性。

4. 卡片列表在不同业务场景中的应用

卡片列表几乎无处不在:

  • 电商应用:商品列表、订单列表、购物车,每个卡片展示商品图、名称、价格、评分;
  • 金融应用:账单列表、交易记录、投资组合,每个卡片展示金额、日期、状态、操作按钮;
  • 社交应用:消息列表、动态流、评论列表,每个卡片展示头像、昵称、内容摘要、互动按钮;
  • 生产力工具:任务列表、项目列表、文件列表,每个卡片展示标题、描述、优先级、截止日期。

在这些场景中,卡片列表都是最常见的选择,因为它能够在有限的空间内展示足够的信息,同时保持良好的可读性和交互性。

5. PC 端卡片列表的特殊考量

在 PC 宽屏上,卡片列表需要一些特殊的适配:

  • 宽度控制:不能让卡片占满整个屏幕宽度,否则每行文字会很长,影响阅读。通常会限制卡片宽度或添加左右留白;
  • 阴影强度:PC 屏幕通常在较亮的环境中使用,弱阴影可能看不清。但也不能太强,否则显得廉价;
  • 鼠标交互:PC 用户使用鼠标,可以为卡片增加悬停效果(如背景色变化、阴影加强、光标变化),提升交互反馈;
  • 键盘导航:支持 Tab 键在卡片间导航,以及 Enter 键触发操作,便于键盘用户;
  • 多选与批量操作:在 PC 端,用户可能希望选中多个卡片进行批量操作(如批量删除、批量导出)。

本案例虽然还没有实现这些高级特性,但已经为你打好了基础。你可以在此基础上继续扩展,例如增加复选框、集成路由、或实现批量操作。

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

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐