DiaryCard 组件设计:情绪色条、置顶标识与多态内容

前言

卡片组件是内容型应用中最常见的 UI 模式。“海风日记“的DiaryCard组件承载了日记的摘要展示功能,包含情绪色条、置顶标识、时间戳、正文摘要、图片占位、标签和情绪 emoji 等丰富元素。

本文将从DiaryCard.ets源码出发,深入讲解卡片组件的设计思路、多态内容展示以及情绪色条映射机制。


一、组件属性设计

1.1 属性定义

@Component export struct DiaryCard { moodColor: MoodColor = 'default' // 情绪色类型 timeStr: string = '' // 时间字符串 content: string = '' // 正文摘要 tags: string[] = [] // 标签数组 isPinned: boolean = false // 是否置顶 hasImage: boolean = false // 是否有图片 moodEmoji: string = '' // 情绪 emoji onTap: () => void = () => {} // 点击回调 }

1.2 属性分类

分类属性类型展示效果
视觉moodColor颜色左侧情绪色条
时间timeStr字符串时间戳
内容content字符串正文摘要
元数据tags,isPinned,hasImage布尔/数组标签、置顶、图片标识
交互moodEmoji,onTap字符串/函数表情图标、点击响应

二、情绪色条

2.1 颜色映射

function getMoodStripColor(mood: MoodColor): string { switch (mood) { case 'sunny': return COLOR_MOOD_SUNNY // 橙色 #F5A623 case 'calm': return COLOR_MOOD_CALM // 薄荷绿 #7ECAAE case 'ponder': return COLOR_MOOD_PONDER // 紫色 #A67EC0 case 'low': return COLOR_MOOD_SAD // 蓝色 #8BAFD6 default: return '#E8D5B0' // 默认米色 } }

2.2 色条实现

Rect() .width(3.5) // 3.5vp 宽 .height('100%') // 与卡片等高 .fill(getMoodStripColor(this.moodColor)) .borderRadius({ topLeft: CARD_RADIUS, bottomLeft: CARD_RADIUS })

2.3 情绪色与心情的对应

心情MoodColor色值色条颜色
开心/晴天sunny#F5A623橙色
平静calm#7ECAAE薄荷绿
感慨ponder#A67EC0紫色
低落low#8BAFD6蓝色
难过sad#B0A8C8淡紫

三、置顶标识

3.1 置顶条

if (this.isPinned) { Row({ space: 4 }) { SymbolGlyph($r('sys.symbol.pin')) .fontSize(10).fontColor([COLOR_PRIMARY_DEEP]) Text('置顶').fontSize(10).fontColor(COLOR_PRIMARY_DEEP) .fontWeight(FontWeight.Bold) } .width('100%') .padding({ left: 18, top: 4, bottom: 4 }) .backgroundColor('rgba(245,166,35,0.06)') }

3.2 置顶标识的视觉设计

  • 图标sys.symbol.pin图钉图标
  • 文字:“置顶“标签
  • 颜色COLOR_PRIMARY_DEEP(深橙色)
  • 背景:极淡橙色背景rgba(245,166,35,0.06)

四、内容展示

4.1 正文摘要

Text(this.content) .fontSize(14.5).fontColor(COLOR_TEXT_MAIN) .lineHeight(25.4) .maxLines(5) // 最多显示 5 行 .textOverflow({ overflow: TextOverflow.Ellipsis }) // 超出省略

4.2 图片占位

if (this.hasImage) { Row() { SymbolGlyph($r('sys.symbol.camera')) .fontSize(20).fontColor(['#C8C0B0']) } .width('100%').height(86) .backgroundColor('#EDE0CC').borderRadius(9) .justifyContent(FlexAlign.Center) .margin({ bottom: 10 }) }

4.3 标签和情绪

Row() { if (this.tags.length > 0) { Text(`#${this.tags[0]}`) // 只显示第一个标签 .fontSize(11).fontColor(COLOR_AMBER) .backgroundColor('rgba(245,166,35,0.08)') .padding({ left: 8, right: 8, top: 2, bottom: 2 }) .borderRadius(8) } Blank() if (this.moodEmoji.length > 0) { Text(this.moodEmoji).fontSize(14) } }

五、卡片布局

5.1 完整布局

Row() { // 左侧情绪色条 Rect() .width(3.5).height('100%') .fill(getMoodStripColor(this.moodColor)) // 卡片内容 Column() { // 置顶标识(可选) if (this.isPinned) { ... } // 内容区 Column({ space: 6 }) { Text(this.timeStr) // 时间戳 Text(this.content) // 正文摘要 if (this.hasImage) { ... } // 图片占位 // 标签 + 情绪 Row() { ... } } } .layoutWeight(1) }

5.2 卡片样式

.width('100%') .backgroundColor(COLOR_CARD_BG) .borderRadius(CARD_RADIUS) .shadow({ radius: 12, color: 'rgba(160,120,60,0.10)', offsetY: 2 }) .clip(true)

六、组件的多态展示

6.1 不同状态下的卡片

状态置顶图片标签情绪
普通
置顶
图文
完整

七、常见问题与排查

7.1 卡片内容溢出

问题:正文内容超出卡片区域。

解决方案:使用maxLinestextOverflow控制文本溢出。

7.2 情绪色条不显示

问题:左侧情绪色条没有显示。

原因:Rect 的height('100%')需要父容器有明确高度。

解决方案:确保 Row 有明确的高度约束。


总结

本文通过“海风日记“的 DiaryCard 组件,深入讲解了卡片组件的设计:

  1. 属性设计:情绪色、时间、内容、标签、交互
  2. 情绪色条:颜色映射和实现
  3. 置顶标识:图标 + 文字 + 背景色
  4. 内容展示:正文摘要、图片占位、标签
  5. 多态展示:不同状态下的卡片样式

下一篇文章将深入讲解SymbolGlyph 与 FontColor 数组语法,敬请期待。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

  • Text 组件文档
  • Rect 组件文档
  • SymbolGlyph 文档
  • 海风日记项目源码
  • [HarmonyOS 开发者官网](https://atomgit.com/openharmony/docs
  • 开源鸿蒙跨平台社区