ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

【知律|17】HarmonyOS ArkTS 亮暗色与视觉令牌实战:集中颜色、间距和交互状态避免页面割裂

【知律|17】HarmonyOS ArkTS 亮暗色与视觉令牌实战:集中颜色、间距和交互状态避免页面割裂 页面视觉割裂通常不是某个颜色“不好看”而是颜色、字号、间距、圆角和交互状态缺少统一语义。同一个紫色有的页面拿它做按钮背景有的页面直接拼透明度做阴影有的页面又写一段相近渐变当产品需要暗色模式或审核要求调整对比度时修改点会散落到几十个文件。本文基于知律项目D:\huawei\one19-11、包名com.jiaweikang.one19的真实源码重点复核 brief 指向的ThemeConstants.ets同时核对EntryAbility.ets、base/element/color.json、dark/element/color.json、GreenButton.ets、TopBar.ets、BankCard.ets、PracticePage.ets与多个页面的颜色使用。项目面向 HarmonyOS 5.0 及以上版本已经集中定义大量视觉常量和按压状态但当前应用明确强制亮色暗色资源也没有提供真正的暗色值因此不能把现状描述为“已经完成亮暗色适配”。一、视觉令牌的核心是语义不是颜色表ThemeConstants.ets中的Colors已经按用途组织static readonly BACKGROUND: string #FFFFFF static readonly SURFACE: string #FFFFFF static readonly TEXT_PRIMARY: string #1A1B2E static readonly TEXT_SECONDARY: string #4A4C66 static readonly TEXT_HINT: string #6B6F85 static readonly SUCCESS: string #2ED573 static readonly ERROR_TEXT: string #D63342这些名称比PURPLE_500、GRAY_900更接近业务语义。页面想表达主要正文时使用TEXT_PRIMARY想表达错误文字时使用ERROR_TEXT。将来暗色主题可以改变具体色值但调用方仍然表达同一个意义。同一个状态也区分了填充和文字static readonly ERROR: string #FF4757 static readonly ERROR_TEXT: string #D63342 static readonly WARNING: string #FFA940 static readonly WARNING_TEXT: string #A66100高饱和色适合图形、图标或色块不一定适合白底小字号正文。把ERROR和ERROR_TEXT分开是比“全应用只用一个红色”更可维护的做法。二、Sizes 已经统一字号、间距和组件尺寸视觉令牌不仅是颜色。Sizes集中保存static readonly H1_FONT: number 22 static readonly H2_FONT: number 18 static readonly TITLE_FONT: number 16 static readonly BODY_FONT: number 14 static readonly CAPTION_FONT: number 12 static readonly SMALL_FONT: number 10 static readonly PADDING_SMALL: number 8 static readonly PADDING_MEDIUM: number 12 static readonly PADDING_LARGE: number 16 static readonly PADDING_XL: number 20页面大量使用Sizes.BODY_FONT、Sizes.PADDING_LARGE和Sizes.CARD_RADIUS比每个页面各写 14、16、24 更容易形成统一节奏。但现有令牌仍是“基础常量”还没有形成完整组件语义。例如卡片 padding、列表行高度、弹窗边距、危险按钮高度依旧需要页面组合。下一步不必继续增加几十个无语义数字而应围绕真实重复模式增加static readonly CARD_PADDING: number 16 static readonly LIST_ROW_MIN_HEIGHT: number 52 static readonly DIALOG_HORIZONTAL_PADDING: number 20 static readonly TOUCH_TARGET_MIN: number 44SMALL_FONT 10适合非常次要的短标签不应被当作普通正文。手机和平板的正常可读文本应优先保持 12vp 以上并在系统字体放大后检查容器是否截断。三、当前应用是主动锁定亮色而不是跟随系统EntryAbility.onCreate中真实代码是this.context .getApplicationContext() .setColorMode( ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT )因此应用启动后主动使用亮色模式。这个策略本身不是错误如果当前所有页面、位图、阴影和状态色只经过亮色验证锁定亮色可以避免系统暗色模式下出现白字白底或黑图标黑背景。但发布材料和技术文章必须准确表达当前是“固定亮色方案”不是“完整支持亮暗色自动切换”。如果产品决定继续锁定亮色验收重点是系统处于暗色时应用仍保持设计好的亮色、状态栏和导航栏图标仍可读如果决定跟随系统则需要完成资源、组件和页面的全链路改造。四、dark 资源目录现在并没有暗色值项目同时存在entry/src/main/resources/base/element/color.json entry/src/main/resources/dark/element/color.json但两份文件中的background、surface、text_primary等值完全相同。例如{ name: background, value: #F5F5F5 }在 dark 目录中仍然是#F5F5F5。这意味着即使取消强制亮色资源限定目录也不会自动提供暗色视觉。更值得注意的是资源文件使用绿色体系primary #4CAF50 primary_dark #388E3C accent #FF9800而ThemeConstants.ets使用紫粉体系PRIMARY #7C5CFC PRIMARY_DARK #5B3FE0 ACCENT #FF6B9D项目因此存在两套视觉真源。当前 ArkTS 页面大量引用Colors资源色可能只在启动窗口或少数配置中使用未来维护者若只修改color.json页面不会自动变成新主题。五、字符串常量集中化仍不等于主题化Colors让色值集中但类型仍是普通字符串static readonly BACKGROUND: string #FFFFFF这意味着编译后的值不会根据dark资源限定目录自动切换。真正的亮暗主题应让同名资源在不同限定目录解析为不同值backgroundColor($r(app.color.background)) fontColor($r(app.color.text_primary))或者建立一个明确的 Theme Provider在主题变化时向组件提供语义色。选择哪种方式取决于项目架构但必须保证只有一个权威来源。迁移时不能机械地把所有十六进制字符串替换为资源。封面遮罩#B3000000、弹窗蒙层#66000000和带 alpha 的阴影是组合语义应分别命名为IMAGE_SCRIM_STRONG、MODAL_BACKDROP、SHADOW_PRIMARY_MEDIUM否则暗色模式下透明叠加仍可能失控。六、alpha 工具解决了格式问题但没有解决语义问题项目提供export function alpha(color: string, alphaHex: string): string { if (!color || color.length 7) return color return # alphaHex color.substring(1, 7) }它正确体现 ArkUI#AARRGGBB的 alpha 在前格式可把主色转换为透明色。这个工具适合生成同源阴影或填充。但页面仍出现许多直接写入的阴影.shadow({ radius: 16, color: #107C5CFC, offsetX: 0, offsetY: 6 })类似#0F7C5CFC、#147C5CFC、#337C5CFC分散在多个页面。虽然它们都围绕主紫色透明度差异却没有命名依据。可以收口为static readonly SHADOW_PRIMARY_SOFT alpha(Colors.PRIMARY, 10) static readonly SHADOW_PRIMARY_MEDIUM alpha(Colors.PRIMARY, 20) static readonly SHADOW_PRIMARY_STRONG alpha(Colors.PRIMARY, 33)页面只选择软、中、强不再自己决定十六进制 alpha。七、交互状态已经开始组件化GreenButton、TopBar、BankCard和CategoryPage都使用Styles与stateStylesStyles function gbPressed() { .opacity(0.78) .scale({ x: 0.97, y: 0.97 }) } Styles function gbNormal() { .opacity(1) .scale({ x: 1, y: 1 }) }按钮应用.stateStyles({ pressed: gbPressed, normal: gbNormal })这让同类按钮拥有一致的按压反馈。TopBar使用更小的 0.94 缩放卡片使用 0.98差异与组件体量相符。不过状态体系尚不完整。真实组件主要覆盖normal和pressed还需要根据业务补齐disabled降低强调度同时阻止点击selected不能只依赖颜色变化还需图标、描边或字重loading保持按钮尺寸稳定避免文字被进度提示挤走focusPC/2in1 键盘导航需要清晰焦点error和success文本、图标、背景使用成套语义令牌。八、按真实色值计算对比度而不是相信注释ThemeConstants.ets的部分注释标记了 “4.6:1 PASS”。发布复查仍应对最终前景和背景组合做计算因为注释可能与实际值不一致。按 WCAG 相对亮度公式计算当前常见组合前景背景实测约值结论#6B6F85TEXT_HINT#FFFFFF4.96:1普通文本可读#D63342ERROR_TEXT#FFFFFF4.76:1普通文本可读#A66100WARNING_TEXT#FFFFFF4.85:1普通文本可读#C73D6DACCENT_TEXT#FFFFFF4.86:1普通文本可读#5B3FE0TAG_TEXT#EFEAFF5.53:1标签文本可读#19A35ASUCCESS_TEXT#FFFFFF3.27:1不满足 4.5:1 普通正文#FFFFFF#7C5CFCPRIMARY4.38:1大字/关键图形可用普通小字需谨慎#FFFFFF#FF6B9DACCENT2.68:1未达到 3:1因此SUCCESS_TEXT旁边“4.6:1 PASS”的注释与计算结果不一致。紫粉渐变按钮上使用白字时最浅区域还可能落到 ACCENT不能只按 PRIMARY 单色评估。这类发现不能靠肉眼争论应把对比度检查变成脚本或设计令牌单元测试。注意阴影、半透明蒙层和图片背景需要按最终合成颜色测试不能只测源色。九、答题状态需要同时编码颜色和语义项目为选项定义了完整配对OPTION_SELECTED_BG OPTION_SELECTED_BORDER OPTION_CORRECT_BG OPTION_CORRECT_BORDER OPTION_WRONG_BG OPTION_WRONG_BORDER这种“背景 边框”组合比单独换文字颜色更稳。答对、答错和选中状态不应只靠绿、红、紫来区分还要配合勾选/错误图标、文本说明和边框变化照顾色觉差异用户。暗色模式中亮绿色背景#DFFAEC和亮红色背景#FFE4E7不能原样放在深色页面上。应为同名语义提供暗色值例如低明度填充搭配高亮边框同时重新计算文本对比度。十、页面仍存在绕过令牌的颜色源码扫描可以看到页面直接写入[#DCD3F7, #E6DAF5, #F4D9E6] // 页面背景渐变 #FFE4E7 // 错误浅背景 #FFF1D6 // 警告浅背景 #66000000 // 弹窗蒙层 #A12530 // 收藏未选中文字其中有些颜色与Colors中现有令牌接近但没有复用有些是页面特定色。判断标准不应是“出现十六进制就全部删除”而是同一视觉含义是否在两个以上位置重复以及它是否需要随主题变化。页面背景渐变在Index、HomePage、MinePage、FavoritePage、BankListPage和ExamTab多次重复明显应升级为统一背景组件或主题令牌。弹窗蒙层也多处出现应使用一个MODAL_BACKDROP。单个图片遮罩可以保留局部实现但最好有清晰名字。十一、推荐的亮暗色迁移路径不能在仍强制亮色时宣称支持暗色。推荐按以下顺序推进盘点所有语义色、硬编码颜色、位图和系统栏样式选择资源限定目录或 Theme Provider 作为唯一主题真源让 base 与 dark 的同名资源真正具有不同值先迁移BACKGROUND、SURFACE、主要文本和分割线再迁移按钮、标签、状态色、阴影、蒙层和图片遮罩补齐 disabled、selected、focus、loading 等交互令牌逐页验证后最后取消COLOR_MODE_LIGHT在跟随系统、强制亮色和主题切换过程中验证生命周期行为。如果产品决定不支持暗色则保留强制亮色并删除或注明无效的 dark 镜像资源避免维护者误以为已有双主题。十二、建立可执行的视觉验收矩阵视觉令牌改造不能只验证首页。知律至少需要检查区域亮色暗色交互状态启动页背景与 Logo启动窗口无闪白点击、转场主导航图标与角标侧栏/底栏可读normal、selected、pressed题库卡片标题与进度卡片层级清晰normal、pressed、focus答题选项选中/对/错状态仍可区分disabled、selected、correct、wrong对话框蒙层和正文表面与背景分层open、saving、error结果页分数与图例渐变和印章可读按钮、返回系统区域状态栏/导航栏图标颜色正确窗口变化每组都要测试正常字号与系统字体放大手机、平板和 PC/2in1 的目标窗口以及低亮度屏幕。关键文本按 4.5:1、关键图标和大文本按 3:1 进行对比度复核。十三、针对当前源码的最小改进清单知律现阶段不需要先建立复杂主题框架。最小且高价值的改动是修正SUCCESS_TEXT的错误对比度注释并选择更深的成功文字色把重复页面渐变、主色阴影和弹窗蒙层收口为语义令牌统一资源目录的绿色体系与 ArkTS 的紫粉体系只保留一个权威来源明确当前“固定亮色”的产品策略和发布说明若准备支持暗色先补齐真正的 dark 色值再取消强制亮色为通用组件增加 disabled、focus 和 loading 状态用脚本持续验证关键前景/背景组合避免注释再次过期。这些步骤都能从现有代码逐步迁移不需要一次重写全部页面。十四、结语知律已经建立了视觉令牌的基础Colors按背景、文本、状态和选项语义分类Sizes统一字号、间距与组件尺寸通用按钮、顶栏和卡片通过stateStyles提供按压反馈。这些设计减少了页面各写一套样式的风险。但当前主题仍有三条明确边界应用强制亮色dark 资源与 base 完全相同资源绿色体系与页面紫粉体系并存。再加上部分硬编码阴影和对比度注释不准确说明“集中常量”还需要继续演进成“单一真源、语义稳定、亮暗可替换、结果可测”的视觉系统。本文由 AI 辅助整理所有技术结论与对比度数据均基于项目真实源码和公开计算公式复核未虚构暗色适配完成状态、审核结果、平台数据、PV、点赞、收藏或推荐结果。
返回列表