HarmonyOS应用开发实战:萌宠日记 - 今日记录卡片与文本溢出处理
·

前言
在 萌宠日记 的首页中,今日记录卡片 用于展示用户当天的日记摘要,包含 时间、标题、正文预览、照片缩略图 等要素。其中 文本溢出处理 是一个关键细节 — 当正文内容超出卡片区域时,如何优雅地截断并显示省略号,保持布局整洁。
本文将从 萌宠日记 的今日记录卡片实现出发,深入解析文本截断、多行溢出、缩略图布局以及卡片内容组织等关键技术。
一、今日记录卡片整体设计
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
更多推荐




所有评论(0)