乒乓球口袋教练 HarmonyOS 学习应用(06):主题 Token 与球台视觉风格
一、视觉切换为什么不能直接改业务页面球台绿、记分卡白底和深色背景都属于视觉语义课程完成度、收藏和练习记录则属于业务事实。如果页面里散落着十几处颜色常量切换深色模式时最容易把文本、分隔线和阴影遗漏同时也诱发组件把视觉选择误当成业务状态。本项目把颜色收敛为 palette把主题模式收敛为 system、light、dark 三个值。// 2. 根据用户在设置页选择的 mode 写入对应 palette 到 AppStorage // 3. UI 用 StorageProp(palette) 拿色用 StorageProp(is_dark) 切图标 / 阴影 export class ThemeManager { private static instance: ThemeManager | null null; private listener: mediaquery.MediaQueryListener | null null; private systemDark: boolean false; private mode: ThemeMode system; static get(): ThemeManager { if (ThemeManager.instance null) { ThemeManager.instance new ThemeManager(); } return ThemeManager.instance; } // 应用启动时调用从持久化恢复 mode默认 system订阅系统主题 init(persistedMode: ThemeMode, systemColorMode?: ConfigurationConstant.ColorMode): void { this.mode persistedMode; AppStorage.setOrCreateThemeMode(KEY_THEME_MODE, this.mode); this.listener mediaquery.matchMediaSync((prefers-color-scheme: dark)); this.systemDark this.listener.matches; this.updateSystemColorMode(systemColorMode, false); this.refreshSystemDark(false);二、ThemeManager 如何确定当前调色板ThemeManager 初始化时读取持久化的 theme_mode并结合 mediaquery 监听系统颜色模式。它把 palette 与 is_dark 写进 AppStorage页面通过 StorageProp 读取同一套 Token。这样课程卡片、设置页和首页并不需要各自监听系统事件视觉更新仍能由一个管理器完成。参与者输入输出或约束模型或配置稳定标识、模式或模块字段给出可追溯的工程事实服务或系统能力经过归一化的请求返回明确结果或失败原因页面回读后的结果只渲染不保存第二份事实} setMode(mode: ThemeMode): void { this.mode mode; AppStorage.setOrCreateThemeMode(KEY_THEME_MODE, mode); if (mode system) { this.refreshSystemDark(false); } this.applyPalette(); } private resolveDark(): boolean { if (this.mode dark) return true; if (this.mode light) return false; return this.systemDark; } private applyPalette(): void { const isDark: boolean this.resolveDark(); const palette: ColorPalette isDark ? DarkPalette : LightPalette; AppStorage.setOrCreateboolean(KEY_IS_DARK, isDark); AppStorage.setOrCreateColorPalette(KEY_PALETTE, palette); }三、设置页只提交模式而不拼接颜色设置页的单选项只调用 ThemeManager.get().setMode(m.id)。setMode 先写入 theme_mode再依据模式调用 apply它不修改课程模型也不会清空正在输入的搜索词。这个边界很重要用户回到课程页看到的是同一份学习数据换了一套色彩而不是一次看起来像“刷新成功”的数据重置。.onClick(() { this.themeMode m.id; ThemeManager.get().setMode(m.id); PreferencesHelper.get().persist(theme_mode, m.id); }); if (i MODE_OPTIONS.length - 1) { Column().width(92%).height(0.5).backgroundColor(this.palette.divider); } }, (m: ModeOption) m.id); } .width(100%) .backgroundColor(this.palette.card) .borderRadius(AppSizes.r3) .clip(true); } .alignItems(HorizontalAlign.Start) .width(100%); } Builder fontSection() { Column({ space: AppSizes.s2 }) { Text(字体大小)四、系统主题变化与人工选择怎样区分system 模式与 dark 模式不能混为一谈。前者允许监听器随系统变化后者是用户明确锁定深色。当用户从 system 改为 light 后系统再次变暗不应覆盖其选择重新选回 system 才恢复监听。若不区分这两条路径设置页的显示值会和实际调色板发生错位。情况容易出现的错误本文采用的处理数据或配置缺项伪造默认成功状态停在可解释的失败或空态页面重进使用上一页残留对象从模型、服务或系统重新回读重复动作再写一遍相同业务事实由稳定入口或回调收敛} export const LightPalette: ColorPalette { primary: #0A84FF, primaryEnd: #5B5BF0, accent: #FF8A00, bg: #F5F7FA, bgElevated: #FFFFFF, card: #FFFFFF, cardOverlay: #00000010, divider: #EAECEF, textPrimary: #1A1A1F, textSecondary: #5A6072, textTertiary: #9097A5, textOnPrimary: #FFFFFF, success: #34C759, danger: #FF3B30, badgeBg: #E6F0FF, badgeText: #0A84FF, tabActive: #0A84FF, tabInactive: #9097A5, shadow: #0F1A3320, scrim: #00000066五、切换后的可读性如何回读验证先在设置页依次选择浅色、深色和跟随系统分别进入首页和课程卡片回读背景、主文字和辅助文字的对比再返回设置页确认选中项与主题一致最后重启应用检查 theme_mode 恢复而课程进度没有变化。配图展示的是深色设置状态不能替代对另两种模式的检查。验收阶段实际动作回读重点前置确认启动正确 bundle 或打开目标页标题、入口与模块身份主题操作执行搜索、切换、完成或跳转服务/系统返回的结果重进检查返回、重启或切换范围后再进入事实没有依赖旧页面残留六、实现边界与维护顺序深浅色切换只改主题模式和调色板 Token课程内容、进度与输入状态不随视觉模式发生第二份写入。 新增需求时应先补齐模型、配置或服务合同再调整页面入口把同一个判断复制到多个组件短期看似方便后续会使结果无法回读。ArkTS 状态管理的基础机制可参考 HarmonyOS 官方文档。七、继续扩展时的约束调色板的变化范围应当只包括表现层。课程模型、视频位置、练习日志和测验成绩即使被写入 AppStorage也不能和 theme_mode 使用同一个含义含混的键。主题状态越独立越能避免一次皮肤升级被误判为学习数据迁移。深色模式的验收要注意可读不是只有文字没有消失。辅助说明、时间戳、未解锁徽章、禁用按钮和卡片边线在低亮度背景上也要保持区分度。把这些元素的角色写进 palette可以让设计调整只影响 Token而不是让每一个页面临时增加深色分支。如果设备系统颜色变化发生在设置页之外页面重新出现时应订阅已经更新的 palette而不需要导航栈逐页重建。这个体验依赖 ThemeManager 的唯一实例因此模块初始化和销毁时要避免重复注册监听器。Token 不能被组件私自覆盖组件可以根据 is_dark 选择图标资源却不应在局部把文本颜色改成另一套固定色。局部覆盖一多设置页显示深色而课程页仍有浅色残留的问题就无法从 ThemeManager 追踪。需要新增视觉角色时应先扩展 palette 定义再让组件消费这个名字明确的角色。设置值的恢复顺序应用重新启动后先恢复 theme_mode再生成 palette最后让页面读取 StorageProp。若先渲染页面再异步补颜色用户会看到短暂的闪白若恢复失败则使用明确的 system 默认值并允许在设置页重新选择而不是留下半初始化的颜色对象。

相关新闻

乒乓球口袋教练 HarmonyOS 学习应用(05):搜索与分类组合过滤

乒乓球口袋教练 HarmonyOS 学习应用(05):搜索与分类组合过滤

一、把关键词和专项筛选放进同一个查询入口 课程多起来以后,用户常常先输入“反手”,再把范围切到相持模块。若关键词和模块按钮分别在页面各自过滤,列表条数、课程标签和点击后的详情很容易不一致。本项目把两个条件交给 SearchService.sea…

2026/7/30 11:54:02阅读更多 →
Layerdivider终极指南:5分钟掌握AI智能分层技术,轻松分离复杂图像元素

Layerdivider终极指南:5分钟掌握AI智能分层技术,轻松分离复杂图像元素

Layerdivider终极指南:5分钟掌握AI智能分层技术,轻松分离复杂图像元素 【免费下载链接】layerdivider A tool to divide a single illustration into a layered structure. 项目地址: https://gitcode.com/gh_mirrors/la/layerdivider 你是否曾经…

2026/7/30 11:54:02阅读更多 →
5分钟快速上手Pure Admin Thin:超轻量Vue3后台管理系统框架

5分钟快速上手Pure Admin Thin:超轻量Vue3后台管理系统框架

5分钟快速上手Pure Admin Thin:超轻量Vue3后台管理系统框架 【免费下载链接】pure-admin-thin vue-pure-admin官方精简版 项目地址: https://gitcode.com/gh_mirrors/pu/pure-admin-thin Pure Admin Thin是基于Vue 3和Element Plus构建的超轻量级后台管理系统…

2026/7/30 11:52:02阅读更多 →
Unity安卓热更新实战:ILRuntime+AssetBundle方案全流程解析

Unity安卓热更新实战:ILRuntime+AssetBundle方案全流程解析

1. 项目概述:为什么我们需要热更? 在移动游戏开发,尤其是Unity安卓项目中,热更新(Hotfix/Hot Update)早已不是“锦上添花”的功能,而是项目稳定运营和快速迭代的“生命线”。想象一下&#xff0…

2026/7/30 13:10:30阅读更多 →
【机器学习案列-43】AI数据中心用水用电分析

【机器学习案列-43】AI数据中心用水用电分析

🧑 博主简介:曾任某智慧城市类企业算法总监,目前在美国市场的物流公司从事高级算法工程师一职,深耕人工智能领域,精通python数据挖掘、可视化、机器学习等,发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…

2026/7/30 13:10:30阅读更多 →
不要把 Skill 写成 Prompt

不要把 Skill 写成 Prompt

不要把 Skill 写成 Prompt:Agent Skill 调优的系统方法与实战心得 Skill 是 Agent 可按需加载的一组领域规则、工作流、工具说明、约束和验证方法。真正有效的 Skill,不是写得越长越好,而是让模型在正确的任务上被正确触发、以最小上下文完成…

2026/7/30 13:10:30阅读更多 →
2027年二建备考启动!3款口碑题库,按需挑选不踩坑

2027年二建备考启动!3款口碑题库,按需挑选不踩坑

26年二级建造师考试已经顺利落下帷幕,发挥不理想、或是计划首次报考2027年二建的考生,现在正是开启提前备考的黄金窗口期。二建知识点繁多、考点细碎,如果等到考前两三个月再突击,很容易时间紧张、复习不充分。提早规划&#xff0…

2026/7/30 13:10:30阅读更多 →
roLabelImg 傻瓜式使用教程

roLabelImg 傻瓜式使用教程

🍼 roLabelImg 傻瓜式使用教程(手把手版)假设你已经安装好了 roLabelImg,下面从打开软件开始,一步一步教你标注。第 0 步:准备工作(先建好文件夹) 在你的电脑上,提前建好…

2026/7/30 13:10:30阅读更多 →
如何高效使用kill-doc脚本:免费文档下载终极攻略

如何高效使用kill-doc脚本:免费文档下载终极攻略

如何高效使用kill-doc脚本:免费文档下载终极攻略 【免费下载链接】kill-doc 看到经常有小伙伴们需要下载一些免费文档,但是相关网站浏览体验不好各种广告,各种登录验证,需要很多步骤才能下载文档,该脚本就是为了解决您…

2026/7/30 13:08:30阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/29 9:47:45阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/30 12:22:27阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/29 7:58:51阅读更多 →
3分钟解锁iOS应用自由:TrollInstallerX让你的iPhone摆脱安装限制 [特殊字符]

3分钟解锁iOS应用自由:TrollInstallerX让你的iPhone摆脱安装限制 [特殊字符]

3分钟解锁iOS应用自由:TrollInstallerX让你的iPhone摆脱安装限制 🚀 【免费下载链接】TrollInstallerX A TrollStore installer for iOS 14.0 - 16.6.1 项目地址: https://gitcode.com/gh_mirrors/tr/TrollInstallerX 你是否曾经因为iOS系统的严格…

2026/7/30 0:00:58阅读更多 →
[GESP202606 四级] 扫雷

[GESP202606 四级] 扫雷

B4557 [GESP202606 四级] 扫雷 https://www.luogu.com.cn/problem/B4557 中国计算机学会(CCF)2026年6月C四级讲解——扫雷 https://www.bilibili.com/video/BV1MCMg6AEXR/ B4557 [GESP202606 四级] 扫雷 https://www.bilibili.com/video/BV1ZKTj6ZEVh/ 2…

2026/7/30 0:00:58阅读更多 →
Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 您是否曾因Windows系统盘空间不足而烦恼?是否遇到过设…

2026/7/30 0:00:58阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/30 0:27:26阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/30 4:47:18阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/29 14:26:42阅读更多 →