鸿蒙应用开发实战【61】— 卡号颜色主题系统CardColor枚举映射

📅 2026/7/17 6:17:42 👁️ 阅读次数 📝 编程学习
鸿蒙应用开发实战【61】— 卡号颜色主题系统CardColor枚举映射

鸿蒙应用开发实战【61】— 卡号颜色主题系统CardColor枚举映射

本文是「号码助手全栈开发系列」第 61 篇,持续更新中…
开源社区:https://openharmonycrossplatform.csdn.net


前言

从第 28 篇开始,每个卡号都有一个color字段用于视觉标识。本篇系统梳理 CardColor 的设计——从类型定义到颜色值映射、从渐变双色到 UI 组件集成。这个设计看似简单,但它串联了数据模型、主题系统、颜色选择器和 AvatarBadge 等多个模块。

本篇涵盖:CardColor 联合类型定义、CARD_COLOR_HEX 颜色值映射表、cardGradient 渐变双色、CardDetailPage 颜色选择器、卡片颜色在 AvatarBadge 中的应用。


一、类型定义

1.1 联合字符串类型

exporttypeCardColor='blue'|'orange'|'green'|'pink'|'purple'

为何选择 string literal union 而非 enum?

  • ArkTS 对 TypeScriptenum编译支持有限,在特定版本中可能存在兼容问题
  • string联合类型与 RDB 存储天然兼容——color字段直接存'blue'字符串
  • 序列化/反序列化无需额外转换,减少了出错概率

1.2 在 Entity 中的使用

exportinterfaceCardEntity{id?:numberlabel:stringphone_number:stringcarrier:stringremark:string/** 显示颜色标识 */color:CardColor// 'blue' | 'orange' | 'green' | 'pink' | 'purple'sort_order:numbercreated_at:numberupdated_at:number}

数据库创建时,color字段定义为TEXT NOT NULL DEFAULT 'blue'


二、颜色值映射

2.1 CARD_COLOR_HEX 调色板

// AppColors.etsstaticreadonlyCARD_COLOR_HEX:string[]=['#4F7CFF',// blue — 品牌蓝'#3CC463',// green — 翡翠绿'#FF2E4D',// pink — 玫瑰红'#FF7A1E',// orange — 活力橙'#7B61FF'// purple — 梦幻紫]

设计原则

  • 5 色满足用户辨识需求,不过多造成选择负担
  • 颜色选中度高,涵盖冷暖色系
  • 与主色#4F7CFF(blue)一致,blue 作为默认值

2.2 cardGradient 渐变双色

每个卡号颜色对应一组渐变双色(用于AvatarBadge头像背景):

staticcardGradient(colorKey:string):[string,string]{switch(colorKey){case'blue':return[AppColors.PRIMARY,AppColors.PRIMARY_2]// #4F7CFF → #7C5CFFcase'green':return['#3CC463','#6BE28E']// 绿 → 浅绿case'pink':return['#FF2E4D','#FF7A90']// 红 → 浅红case'orange':return['#FF7A1E','#FFB067']// 橙 → 浅橙case'purple':return['#7B61FF','#9B85FF']// 紫 → 浅紫default:return[AppColors.PRIMARY,AppColors.PRIMARY_2]}}

default 兜底:当数据库中存储了非法 color 值时,使用 blue 作为安全默认值。


三、UI 中的使用

3.1 AvatarBadge 头像

AvatarBadge({text:card.label,colorStart:AppColors.cardGradient(card.color)[0],colorEnd:AppColors.cardGradient(card.color)[1],badgeSize:64,radius:18,fontSize:18})

CardDetailPage中展示卡号大头像时,利用cardGradient'blue'这样的字符串映射为['#4F7CFF', '#7C5CFF'],形成渐变头像。

3.2 颜色选择器 Swatches

constCOLOR_KEYS:CardColor[]=['blue','green','pink','orange','purple']Row({space:10}){ForEach(COLOR_KEYS,(key:CardColor,index:number)=>{Stack(){if(this.selectedColorIndex===index){Text('✓').fontSize(Size.font12).fontWeight(800).fontColor('#FFFFFF')}}.width(Size.s30).height(Size.s30).borderRadius(Size.s9).backgroundColor(AppColors.CARD_COLOR_HEX[index])// 直接索引取色.border(this.selectedColorIndex===index?{width:2.5,color:'#FFFFFF',radius:9}:{width:0}).shadow(this.selectedColorIndex===index?{radius:10,color:AppColors.CARD_COLOR_HEX[index],offsetY:4}:{radius:0,color:'#00000000',offsetY:0}).onClick(()=>{this.selectedColorIndex=index})})}

交互细节

  • 选中态:白色边框 + 外阴影 +对勾
  • 非选中态:无边框无阴影
  • CARD_COLOR_HEX[index]直接索引——COLOR_KEYS数组顺序与 hex 数组一一对应

3.3 保存时回写

// CardDetailPage.onSaveawaitCardDao.update({...card,color:COLOR_KEYS[this.selectedColorIndex],// CardColor 字符串值updated_at:now})

selectedColorIndex映射回CardColor字符串,直接写入数据库。


四、完整设计回顾

┌──────────────────────────────────────────────────────────────┐ │ CardColor 系统全景图 │ ├──────────────────────────────────────────────────────────────┤ │ │ │ Models.ets AppColors.ets CardDetailPage │ │ ┌───────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ CardColor │───────▶│CARD_COLOR_ │───────▶│ 颜色选择器 │ │ │ │ = union │ │ HEX[5] │ │ swatches │ │ │ └───────────┘ ├─────────────┤ ├─────────────┤ │ │ ┌───────────┐ │cardGradient │───────▶│ AvatarBadge │ │ │ │CardEntity │ │( ) → [s,e] │ │ 渐变头像 │ │ │ │.color │ └─────────────┘ └─────────────┘ │ │ └───────────┘ │ │ │ │ │ ▼ │ │ RDB: cards.color = 'blue' / 'green' / 'pink' / ... │ │ (TEXT NOT NULL DEFAULT 'blue') │ │ │ └──────────────────────────────────────────────────────────────┘

数据流:用户在颜色选择器选择 → index → CardColor 字符串 → RDB 存储 → 再次加载时通过cardGradient渲染


五、设计对比

5.1 CardColor 与枚举方案对比

维度联合类型(当前方案)TypeScript enum
ArkTS 兼容性✅ 完全兼容⚠️ 有限支持
数据库存储直接存 ‘blue’,无需转换需存数字或字符串值
序列化天然兼容 JSON需额外转换逻辑
扩展性类型 + hex + gradient 四步自动序号,但需处理映射
编译时安全✅ 类型检查严格✅ 类型安全

5.2 扩展性考虑

如果需要增加新颜色:

// 1. 类型定义加一项exporttypeCardColor='blue'|'orange'|'green'|'pink'|'purple'|'teal'// 2. 颜色常量加 hexstaticreadonlyCARD_COLOR_HEX:string[]=[...,'#00BFA5']// 3. cardGradient 加新 casecase'teal':return['#00BFA5','#64FFDA']// 4. COLOR_KEYS 数组加一项constCOLOR_KEYS:CardColor[]=['blue','green','pink','orange','purple','teal']

四步即可无缝扩展,体现了解耦设计的优势。


小结

要点说明
类型定义type CardColor = 'blue' | 'orange' | ...联合类型
颜色映射CARD_COLOR_HEX[5] 对应 5 色调色板
渐变双色cardGradient(key) → [start, end] 渐变对
颜色选择器索引匹配,选中态白边 + 阴影 + ✓
存储RDB TEXT 字符串,default blue
扩展类型 + hex + gradient + 数组 四步新增颜色

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


相关资源:

  • openHarmony 跨平台社区:https://openharmonycrossplatform.csdn.net
  • HarmonyOS 官方文档:https://developer.huawei.com/consumer/cn/doc/
  • HarmonyOS 颜色资源开发指南:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/resource-categories-and-access
  • HarmonyOS 主题换肤开发:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/theme-switch