前言
在萌宠日记的首页中,今日记录卡片用于展示用户当天的日记摘要,包含时间、标题、正文预览、照片缩略图等要素。其中文本溢出处理是一个关键细节 — 当正文内容超出卡片区域时,如何优雅地截断并显示省略号,保持布局整洁。
本文将从萌宠日记的今日记录卡片实现出发,深入解析文本截断、多行溢出、缩略图布局以及卡片内容组织等关键技术。
一、今日记录卡片整体设计
1.1 卡片结构
┌─────────────────────────────────────┐ │ 今日记录 10:30 │ ← 标题行 ├─────────────────────────────────────┤ │ 愉快的一天 │ ← 日记标题(加粗) │ 今天带豆豆去公园散步,开心地跑 │ ← 正文预览(最多2行,省略号) │ 来跑去... │ │ ┌────┐ ┌────┐ ┌────┐ │ ← 照片缩略图 │ │🐶 │ │🐶 │ │🐶 │ │ │ └────┘ └────┘ └────┘ │ └─────────────────────────────────────┘1.2 完整代码
// HomePage.ets — 今日记录卡片 Column({ space: 12 }) { // 标题行 Row() { Text('今日记录') .fontSize(16) .fontWeight(FontWeight.Bold) .fontColor('#333333') Blank() Text('10:30') .fontSize(12) .fontColor('#999999') } .width('100%') // 记录内容卡片 Column({ space: 8 }) { // 日记标题 Text('愉快的一天') .fontSize(15) .fontWeight(FontWeight.Medium) .fontColor('#333333') .width('100%') // 正文预览 Text('今天带豆豆去公园散步,开心地跑来跑去,还遇到了好朋友...') .fontSize(13) .fontColor('#666666') .width('100%') .maxLines(2) .textOverflow({ overflow: TextOverflow.Ellipsis }) // 照片缩略图 Row({ space: 8 }) { ForEach([0, 1, 2], (_: number) => { Column() { Text('🐶').fontSize(24) } .width(72).height(72) .backgroundColor('#FFF3E0') .borderRadius(12) .justifyContent(FlexAlign.Center) }) } .width('100%') } .width('100%') .padding(16) .backgroundColor('#FFFFFF') .borderRadius(12) } .width('100%') .padding({ left: 16, right: 16 })提示:
maxLines和textOverflow是 Text 组件中控制文本溢出的两个核心属性,maxLines限制最大行数,textOverflow定义溢出时的处理方式(省略号、截断等)。
二、文本溢出处理
2.1 核心属性
Text('今天带豆豆去公园散步,开心地跑来跑去,还遇到了好朋友...') .fontSize(13) .fontColor('#666666') .width('100%') .maxLines(2) // 最多显示 2 行 .textOverflow({ overflow: TextOverflow.Ellipsis }) // 溢出时显示省略号2.2 文本溢出模式
TextOverflow枚举支持三种溢出模式:
| 模式 | 效果 | 说明 |
|---|---|---|
TextOverflow.Ellipsis | 显示省略号... | ✅ 萌宠日记使用,适合内容预览 |
TextOverflow.Clip | 直接截断 | 适合精确控制宽度 |
TextOverflow.None | 不处理,内容溢出 | 默认行为,不推荐 |
2.3 多行文本截断
// 单行截断 Text('长文本内容...') .maxLines(1) .textOverflow({ overflow: TextOverflow.Ellipsis }) // 两行截断(萌宠日记使用) Text('长文本内容...') .maxLines(2) .textOverflow({ overflow: TextOverflow.Ellipsis }) // 三行截断 Text('长文本内容...') .maxLines(3) .textOverflow({ overflow: TextOverflow.Ellipsis })三、标题行布局
3.1 标题行结构
Row() { Text('今日记录') // 左侧标题 .fontSize(16) .fontWeight(FontWeight.Bold) Blank() // 弹性占位,将左右两侧分开 Text('10:30') // 右侧时间 .fontSize(12) .fontColor('#999999') } .width('100%')3.2 Blank() 的弹性占位
Blank()组件会占据所有剩余空间,将左右两侧的元素推到两端:
┌─────────────────────────────────────┐ │ 今日记录 Blank() 10:30 │ │ ← 固定宽度 → ← 弹性占位 → ← 固定宽度 → │ └─────────────────────────────────────┘四、内容卡片设计
4.1 卡片嵌套
// 外层:标题行 + 内容卡片的 Column Column({ space: 12 }) { // 标题行 Row() { ... } // 内层:白色卡片 Column({ space: 8 }) { // 标题、正文、缩略图 } .padding(16) .backgroundColor('#FFFFFF') .borderRadius(12) }4.2 嵌套卡片 vs 独立卡片
| 对比维度 | 嵌套卡片 | 独立卡片 |
|---|---|---|
| 结构层次 | 标题在外,卡片在内 | 标题和内容在同一卡片 |
| 视觉风格 | 标题与卡片分离 | 标题与卡片一体 |
| 萌宠日记选择 | ✅ 使用 | — |
五、照片缩略图布局
5.1 缩略图网格
Row({ space: 8 }) { ForEach([0, 1, 2], (_: number) => { Column() { Text('🐶').fontSize(24) // Emoji 占位 } .width(72).height(72) .backgroundColor('#FFF3E0') .borderRadius(12) .justifyContent(FlexAlign.Center) }) } .width('100%')5.2 缩略图参数
| 参数 | 值 | 说明 |
|---|---|---|
| 尺寸 | 72×72vp | 标准缩略图大小 |
| 间距 | 8vp | 缩略图之间的间距 |
| 圆角 | 12vp | 圆角矩形 |
| 背景色 | #FFF3E0 | 浅橙,与主色调呼应 |
| 数量 | 3 张 | 最多展示 3 张缩略图 |
六、数据状态管理
6.1 空状态处理
// 当没有今日记录时,显示提示文字 if (this.hasTodayRecord) { // 显示记录卡片 this.renderRecordCard() } else { // 显示空状态 Column() { Text('今天还没有记录哦~') .fontSize(14) .fontColor('#999999') Button('写一篇日记') .fontSize(13) .fontColor('#F5A623') .backgroundColor('#FFF3E0') .borderRadius(16) .margin({ top: 8 }) } .width('100%') .padding(24) .backgroundColor('#FFFFFF') .borderRadius(12) .alignItems(HorizontalAlign.Center) }6.2 数据加载状态
@State isLoading: boolean = true @State hasError: boolean = false aboutToAppear(): void { this.loadTodayRecord() } loadTodayRecord(): void { this.isLoading = true // 模拟数据加载 try { // 加载今日记录数据 this.isLoading = false } catch (err) { this.hasError = true this.isLoading = false } }七、卡片点击交互
7.1 点击跳转
// 点击卡片跳转到日记详情 Column({ space: 8 }) { // 日记内容... } .width('100%') .padding(16) .backgroundColor('#FFFFFF') .borderRadius(12) .onClick(() => { // 跳转到日记详情页 if (this.onNavigateToDiaryDetail) { this.onNavigateToDiaryDetail() } })7.2 点击反馈
.onClick(() => { // 点击跳转 }) .clickEffect({ level: ClickEffectLevel.LIGHT }) // 轻量点击涟漪八、卡片阴影与圆角
8.1 阴影配置
// 内层卡片未设置阴影,保持简洁 .backgroundColor('#FFFFFF') .borderRadius(12) // 没有 shadow 属性,与宠物信息卡片形成对比8.2 卡片样式对比
| 卡片 | 阴影 | 圆角 | 背景色 | 用途 |
|---|---|---|---|---|
| 宠物信息卡片 | ✅ 有阴影 | 16vp | 白色 | 突出显示 |
| 今日记录卡片 | ❌ 无阴影 | 12vp | 白色 | 内容展示 |
| 健康提醒卡片 | ❌ 无阴影 | 12vp | 白色 | 列表项 |
九、图片加载优化
9.1 真实图片加载
// 缩略图真实图片加载(替代 Emoji 占位) Row({ space: 8 }) { ForEach(this.photos, (photo: PhotoInfo) => { Image(photo.uri) .width(72) .height(72) .borderRadius(12) .objectFit(ImageFit.Cover) // 裁剪填充,保持比例 .onLoad(() => { console.log('Thumbnail loaded') }) .onError(() => { // 加载失败显示占位图 }) }) }9.2 图片加载优化
| 优化策略 | 说明 |
|---|---|
| 缩略图预加载 | 提前加载缩略图,减少等待时间 |
| 懒加载 | 只在可见区域加载图片 |
| 内存缓存 | 使用 Image 组件的默认缓存机制 |
| 占位图 | 加载失败时显示 Emoji 占位 |
十、最佳实践
10.1 文本溢出处理原则
有序列表 — 文本溢出处理的 5 个原则:
- maxLines 控制行数:预览内容通常限制 2-3 行
- Ellipsis 省略号:使用
TextOverflow.Ellipsis提示更多内容 - width 100%:Text 组件必须设置宽度,溢出才能生效
- 合理字号:预览文字使用 13-14fp,避免过大或过小
- 与详情页衔接:预览被截断,点击后进入详情页查看完整内容
10.2 萌宠日记今日记录卡片总结
| 设计要素 | 值 | 说明 |
|---|---|---|
| 标题行 | 今日记录 + 时间 | 左右分布 |
| 日记标题 | 15fp 加粗 | 中等强调 |
| 正文预览 | 13fp, 2 行限制 | 带省略号 |
| 缩略图 | 72×72, 3 张 | 圆角 12vp |
| 内边距 | 16vp | 内容与卡片边缘 |
| 背景色 | 白色 | 与页面背景区分 |
总结
本文从萌宠日记的今日记录卡片实现出发,深入解析了文本溢出处理和卡片布局的完整方法:
- 卡片结构:标题行 + 内容卡片 + 照片缩略图
- 文本溢出:maxLines + textOverflow 控制多行截断
- 三种模式:Ellipsis 省略号、Clip 截断、None 不处理
- 标题行布局:Row + Blank 实现左右分布
- 缩略图布局:Row + ForEach 渲染 3 张图片
- 空状态处理:无记录时显示提示和引导按钮
- 点击交互:点击卡片跳转详情页
- 图片加载:占位图、缓存、懒加载策略
文本溢出处理是 UI 开发中常见但重要的细节,合理的截断策略能让内容预览既简洁又完整。
下一篇我们将深入健康提醒列表与动态数据绑定,解析首页健康提醒区域的实现。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
- Text 组件参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-text
- TextOverflow 枚举:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-text
- Blank 组件:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-blank
- Row 组件参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-row
- Image 组件:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-image
- 点击效果:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-click-effect
- 图片加载优化:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/image-optimization
- 卡片设计指南:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/design-cards