【鸿蒙原生开发实战】第五篇主题切换与发布准备——深色模式、设置页面、签名与构建前言经过前面四篇的开发「知墨」笔记应用的核心功能已经完备。但一个完整的应用还需要深色/浅色主题切换——提升用户体验设置页面——整合数据管理功能Seed 数据——方便初次体验构建与签名——生成可发布的 HAP 包本篇是系列的收官之作我们将完成以上所有内容把一个开发中的项目变成可交付的应用。一、深色/浅色主题切换1.1 主题架构设计主题切换涉及三个层面层面实现方式影响范围系统级setColorMode()系统控件状态栏、对话框颜色资源$r(app.color.xxx)所有引用了颜色资源的 UI 组件自定义状态AppStorage传递 theme 标志业务组件的条件渲染1.2 ThemeService 实现前面第二篇已经介绍了 ThemeService 的初始化部分这里聚焦切换逻辑asynctoggle():Promiseboolean{awaitthis.setDarkMode(!this.isDark);returnthis.isDark;}privateapplyTheme():void{AppStorage.setOrCreate(isDarkTheme,this.isDark);try{constctxAppStorage.getContext(appContext);if(ctx){ctx.getApplicationContext().setColorMode(this.isDark?ConfigurationConstant.ColorMode.COLOR_MODE_DARK:ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT,);}}catch(e){/* ignore */}}关键点setColorMode()是 ApplicationContext 的 API必须通过应用级 Context 调用AppStorage.setOrCreate(isDarkTheme, this.isDark)将主题状态存入全局存储后续其他组件可以通过StorageProp(isDarkTheme)监听主题变化1.3 颜色资源文件在entry/src/main/resources/base/element/color.json中定义了主题色板{color:[{name:background,value:#FFF5F5F5},{name:surface,value:#FFFFFFFF},{name:surface_variant,value:#FFF0F0F3},{name:primary,value:#FF6C5CE7},{name:text_primary,value:#FF1A1A2E},{name:text_secondary,value:#FF6C6C80},{name:border,value:#FFE8E8EE},{name:shadow,value:#0A000000},{name:danger,value:#FFE17055}]}这是浅色主题的颜色定义。深色主题需要在resources/dark/element/color.json中覆盖{color:[{name:background,value:#FF0D0D1A},{name:surface,value:#FF1A1A2E},{name:surface_variant,value:#FF252540},{name:primary,value:#FF8B7CFA},{name:text_primary,value:#FFEEEEF0},{name:text_secondary,value:#FF9E9EB0},{name:border,value:#FF2E2E45},{name:shadow,value:#30000000},{name:danger,value:#FFE17055}]}HarmonyOS 资源覆盖机制系统会自动根据setColorMode()设置的主题加载对应dark/或base/目录下的资源开发者只需要在 color.json 中定义好两套颜色组件中用$r(app.color.background)引用即可。二、SettingsPage 设置页面2.1 页面组成设置页面包含三个分组设置 ├── 外观 │ ├── 深色模式 → [Switch 开关] │ └── 笔记数量 → 共 X 篇笔记 ├── 数据管理 │ ├── [添加示例笔记] 按钮 │ └── [重置所有数据] 按钮 └── 关于 ├── 应用名称 → 知墨 ├── 版本 → 1.0.0 └── 技术栈 → ArkTS Preferences2.2 深色模式开关Row(){Column({space:4}){Text(深色模式).fontSize(15)Text(切换浅色/深色主题).fontSize(12).fontColor($r(app.color.text_secondary))}.layoutWeight(1)Toggle({type:ToggleType.Switch,isOn:this.isDark}).onChange((){this.onToggleTheme();})}ArkUI 的Toggle({ type: ToggleType.Switch })提供了标准的 Switch 组件。isOn参数控制开关状态。2.3 示例数据填充为了让用户第一次打开应用时有内容可看SettingsPage 内置了 5 条示例笔记asynconAddSampleData():Promisevoid{constsamples:string[][][[HarmonyOS 开发入门,HarmonyOS 是华为开发的分布式操作系统...,tech,HarmonyOS,ArkTS],[周末爬山计划,周六早上8点出发带上水和干粮...,life,运动,周末],[项目周报模板,1. 本周完成事项\n2. 遇到的问题...,work,工作,模板],[设计模式笔记观察者模式,观察者模式定义了对象之间的一对多依赖...,study,设计模式,编程],[App 新功能构思,1. 数据导出为 Markdown\n2. 笔记分享...,idea,产品,功能],];for(constsofsamples){consttagLists[3].split(,).map(tt.trim());awaitnoteUseCases.addNote(s[0],s[1],s[2],tagList);}awaitthis.loadStats();}每条笔记覆盖了不同的分类技术、生活、工作、学习、灵感方便测试分类筛选功能。2.4 数据重置asynconResetData():Promisevoid{AlertDialog.show({title:重置数据,message:确定要清除全部${this.noteCount}篇笔记吗此操作不可撤销。,primaryButton:{value:取消,action:(){}},secondaryButton:{value:清除,action:async(){constallNotesawaitnoteUseCases.getAllNotes();for(constnoteofallNotes){awaitnoteUseCases.deleteNote(note.id);}awaitnoteUseCases.reload();awaitthis.loadStats();}}});}设计考虑noteCount动态显示当前笔记数量让用户清楚重置会丢失多少数据。危险的清除按钮用红色$r(app.color.danger)高亮警示。三、color.json 完整配置为了让主题切换生效需要确保entry/src/main/resources/目录下有以下结构resources/ ├── base/ │ ├── element/ │ │ ├── color.json # 浅色主题颜色 │ │ ├── string.json # 字符串资源 │ │ └── boolean.json # 布尔资源 │ ├── media/ # 图片资源 │ └── profile/ │ └── main_pages.json # 页面路由注册 ├── dark/ │ └── element/ │ └── color.json # 深色主题颜色覆盖 ├── en_US/ # 英文资源可选 └── zh_CN/ # 中文资源四、构建 Release 包与签名4.1 生成签名文件在 DevEco Studio 中生成签名证书的步骤打开Build → Generate Key and CSR填写证书信息Alias: knowink_keyValidity: 25 yearsKey Algorithm: RSA 2048生成的.p12文件和.csr文件保存在项目sign/目录下4.2 配置签名在build-profile.json5中添加签名配置{ app: { signingConfigs: [ { name: default, material: { storeFile: ./sign/knowink.p12, storePassword: your_password, keyAlias: knowink_key, keyPassword: your_password, profileFile: ./sign/knowink_release.p7b, certpath: ./sign/knowink_release.cer } } ], // ... } }注意实际密码不要明文提交到 Git。可以使用环境变量或.gitignore排除签名文件。我们项目中已经配置了signingConfigs: []空数组请按需添加。4.3 构建 HAP 包# Debug 构建 hvigorw assembleHap --mode debug # Release 构建需要配置签名 hvigorw assembleHap --mode release构建产物位于entry/build/default/outputs/ ├── default/ │ ├── entry-default-debug.hap # Debug 包 │ └── entry-default-signed.hap # 签名包Release └── entry-default-unsigned.hap # 未签名包五、项目文件总览至此「知墨」笔记应用共包含 17 个源文件层文件行数约职责Domainmodels/Note.ts32笔记实体定义models/Category.ts22分类定义usecases/NoteUseCases.ts52业务用例编排Datarepositories/NoteRepository.ts148数据持久化仓库services/PreferencesService.ts40Preferences 封装services/ThemeService.ts49主题管理UIcore/NoteCard.ets90笔记卡片组件core/StatsCard.ets30统计卡片组件core/EmptyState.ets25空状态占位组件core/CategoryBadge.ets22分类徽章组件PagesIndex.ets228主页面NoteDetailPage.ets199笔记详情页NoteEditPage.ets184新建/编辑页SearchPage.ets117搜索页SettingsPage.ets199设置页EntryEntryAbility.ets48Ability 入口EntryBackupAbility.ets-备份 Ability总代码量约 1500 行 ArkTS 代码实现了完整的笔记 CRUD、分类管理、搜索、主题切换等功能。六、开发心得与避坑指南6.1 构建踩坑回顾问题原因解决方案DEVECO_SDK_HOMEInvaliddaemon 缓存旧环境变量--stop-daemon后重试build-profile.json5not found在错误目录执行 hvigorwcd 到项目根目录EPERM mkdir在工具目录下执行构建在项目目录执行Preferences 数据丢失未调flush()put 后显式调用 flush6.2 后续可扩展方向「知墨」目前是一个单机笔记应用如果需要继续迭代可以考虑数据云同步基于华为云AGConnect的云数据库实现多设备同步富文本编辑支持 Markdown 渲染图片附件使用kit.MediaLibraryKit访问相册Widget 卡片在桌面上展示最近笔记语音输入基于kit.VoiceCallKit的语音转文字分布式协同利用 HarmonyOS 分布式数据管理在多设备间流转七、系列总结五篇博文路线图第一篇环境搭建与项目初始化 ↓ DevEco Studio 安装、SDK 配置、hvigor 构建、项目结构 第二篇数据层与核心架构 ↓ Clean Architecture、领域模型、Repository、Preferences 第三篇UI组件与主页开发 ↓ CategoryBadge/StatsCard/NoteCard/EmptyState、主页面 第四篇多页面路由与交互 ↓ 详情页、编辑页、搜索页、路由机制、表单校验 第五篇主题切换与发布准备 ↓ 深色模式、设置页、签名、构建 HAP、项目总结学习收获通过「知墨」笔记应用的完整开发我们实践了✅ArkTS 语言interface、class、async/await、装饰器语法✅ArkUI 声明式框架Component、State、Prop、build() 链式调用✅页面路由router.pushUrl/back/getParams、页面注册✅数据持久化Preferences API、JSON 序列化✅组件化设计自定义组件拆分、Props 传递、回调函数✅主题管理AppStorage、setColorMode、资源覆盖机制✅构建发布hvigorw、签名配置、HAP 打包开发环境DevEco Studio 6.1 | HarmonyOS SDK 6.1.0 (API 23) | ArkTS ArkUI如果你对这个项目有任何问题或建议欢迎在评论区讨论
【鸿蒙原生开发实战】第五篇:主题切换与发布准备——深色模式、设置页面、签名与构建
发布时间:2026/6/5 12:54:15
【鸿蒙原生开发实战】第五篇主题切换与发布准备——深色模式、设置页面、签名与构建前言经过前面四篇的开发「知墨」笔记应用的核心功能已经完备。但一个完整的应用还需要深色/浅色主题切换——提升用户体验设置页面——整合数据管理功能Seed 数据——方便初次体验构建与签名——生成可发布的 HAP 包本篇是系列的收官之作我们将完成以上所有内容把一个开发中的项目变成可交付的应用。一、深色/浅色主题切换1.1 主题架构设计主题切换涉及三个层面层面实现方式影响范围系统级setColorMode()系统控件状态栏、对话框颜色资源$r(app.color.xxx)所有引用了颜色资源的 UI 组件自定义状态AppStorage传递 theme 标志业务组件的条件渲染1.2 ThemeService 实现前面第二篇已经介绍了 ThemeService 的初始化部分这里聚焦切换逻辑asynctoggle():Promiseboolean{awaitthis.setDarkMode(!this.isDark);returnthis.isDark;}privateapplyTheme():void{AppStorage.setOrCreate(isDarkTheme,this.isDark);try{constctxAppStorage.getContext(appContext);if(ctx){ctx.getApplicationContext().setColorMode(this.isDark?ConfigurationConstant.ColorMode.COLOR_MODE_DARK:ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT,);}}catch(e){/* ignore */}}关键点setColorMode()是 ApplicationContext 的 API必须通过应用级 Context 调用AppStorage.setOrCreate(isDarkTheme, this.isDark)将主题状态存入全局存储后续其他组件可以通过StorageProp(isDarkTheme)监听主题变化1.3 颜色资源文件在entry/src/main/resources/base/element/color.json中定义了主题色板{color:[{name:background,value:#FFF5F5F5},{name:surface,value:#FFFFFFFF},{name:surface_variant,value:#FFF0F0F3},{name:primary,value:#FF6C5CE7},{name:text_primary,value:#FF1A1A2E},{name:text_secondary,value:#FF6C6C80},{name:border,value:#FFE8E8EE},{name:shadow,value:#0A000000},{name:danger,value:#FFE17055}]}这是浅色主题的颜色定义。深色主题需要在resources/dark/element/color.json中覆盖{color:[{name:background,value:#FF0D0D1A},{name:surface,value:#FF1A1A2E},{name:surface_variant,value:#FF252540},{name:primary,value:#FF8B7CFA},{name:text_primary,value:#FFEEEEF0},{name:text_secondary,value:#FF9E9EB0},{name:border,value:#FF2E2E45},{name:shadow,value:#30000000},{name:danger,value:#FFE17055}]}HarmonyOS 资源覆盖机制系统会自动根据setColorMode()设置的主题加载对应dark/或base/目录下的资源开发者只需要在 color.json 中定义好两套颜色组件中用$r(app.color.background)引用即可。二、SettingsPage 设置页面2.1 页面组成设置页面包含三个分组设置 ├── 外观 │ ├── 深色模式 → [Switch 开关] │ └── 笔记数量 → 共 X 篇笔记 ├── 数据管理 │ ├── [添加示例笔记] 按钮 │ └── [重置所有数据] 按钮 └── 关于 ├── 应用名称 → 知墨 ├── 版本 → 1.0.0 └── 技术栈 → ArkTS Preferences2.2 深色模式开关Row(){Column({space:4}){Text(深色模式).fontSize(15)Text(切换浅色/深色主题).fontSize(12).fontColor($r(app.color.text_secondary))}.layoutWeight(1)Toggle({type:ToggleType.Switch,isOn:this.isDark}).onChange((){this.onToggleTheme();})}ArkUI 的Toggle({ type: ToggleType.Switch })提供了标准的 Switch 组件。isOn参数控制开关状态。2.3 示例数据填充为了让用户第一次打开应用时有内容可看SettingsPage 内置了 5 条示例笔记asynconAddSampleData():Promisevoid{constsamples:string[][][[HarmonyOS 开发入门,HarmonyOS 是华为开发的分布式操作系统...,tech,HarmonyOS,ArkTS],[周末爬山计划,周六早上8点出发带上水和干粮...,life,运动,周末],[项目周报模板,1. 本周完成事项\n2. 遇到的问题...,work,工作,模板],[设计模式笔记观察者模式,观察者模式定义了对象之间的一对多依赖...,study,设计模式,编程],[App 新功能构思,1. 数据导出为 Markdown\n2. 笔记分享...,idea,产品,功能],];for(constsofsamples){consttagLists[3].split(,).map(tt.trim());awaitnoteUseCases.addNote(s[0],s[1],s[2],tagList);}awaitthis.loadStats();}每条笔记覆盖了不同的分类技术、生活、工作、学习、灵感方便测试分类筛选功能。2.4 数据重置asynconResetData():Promisevoid{AlertDialog.show({title:重置数据,message:确定要清除全部${this.noteCount}篇笔记吗此操作不可撤销。,primaryButton:{value:取消,action:(){}},secondaryButton:{value:清除,action:async(){constallNotesawaitnoteUseCases.getAllNotes();for(constnoteofallNotes){awaitnoteUseCases.deleteNote(note.id);}awaitnoteUseCases.reload();awaitthis.loadStats();}}});}设计考虑noteCount动态显示当前笔记数量让用户清楚重置会丢失多少数据。危险的清除按钮用红色$r(app.color.danger)高亮警示。三、color.json 完整配置为了让主题切换生效需要确保entry/src/main/resources/目录下有以下结构resources/ ├── base/ │ ├── element/ │ │ ├── color.json # 浅色主题颜色 │ │ ├── string.json # 字符串资源 │ │ └── boolean.json # 布尔资源 │ ├── media/ # 图片资源 │ └── profile/ │ └── main_pages.json # 页面路由注册 ├── dark/ │ └── element/ │ └── color.json # 深色主题颜色覆盖 ├── en_US/ # 英文资源可选 └── zh_CN/ # 中文资源四、构建 Release 包与签名4.1 生成签名文件在 DevEco Studio 中生成签名证书的步骤打开Build → Generate Key and CSR填写证书信息Alias: knowink_keyValidity: 25 yearsKey Algorithm: RSA 2048生成的.p12文件和.csr文件保存在项目sign/目录下4.2 配置签名在build-profile.json5中添加签名配置{ app: { signingConfigs: [ { name: default, material: { storeFile: ./sign/knowink.p12, storePassword: your_password, keyAlias: knowink_key, keyPassword: your_password, profileFile: ./sign/knowink_release.p7b, certpath: ./sign/knowink_release.cer } } ], // ... } }注意实际密码不要明文提交到 Git。可以使用环境变量或.gitignore排除签名文件。我们项目中已经配置了signingConfigs: []空数组请按需添加。4.3 构建 HAP 包# Debug 构建 hvigorw assembleHap --mode debug # Release 构建需要配置签名 hvigorw assembleHap --mode release构建产物位于entry/build/default/outputs/ ├── default/ │ ├── entry-default-debug.hap # Debug 包 │ └── entry-default-signed.hap # 签名包Release └── entry-default-unsigned.hap # 未签名包五、项目文件总览至此「知墨」笔记应用共包含 17 个源文件层文件行数约职责Domainmodels/Note.ts32笔记实体定义models/Category.ts22分类定义usecases/NoteUseCases.ts52业务用例编排Datarepositories/NoteRepository.ts148数据持久化仓库services/PreferencesService.ts40Preferences 封装services/ThemeService.ts49主题管理UIcore/NoteCard.ets90笔记卡片组件core/StatsCard.ets30统计卡片组件core/EmptyState.ets25空状态占位组件core/CategoryBadge.ets22分类徽章组件PagesIndex.ets228主页面NoteDetailPage.ets199笔记详情页NoteEditPage.ets184新建/编辑页SearchPage.ets117搜索页SettingsPage.ets199设置页EntryEntryAbility.ets48Ability 入口EntryBackupAbility.ets-备份 Ability总代码量约 1500 行 ArkTS 代码实现了完整的笔记 CRUD、分类管理、搜索、主题切换等功能。六、开发心得与避坑指南6.1 构建踩坑回顾问题原因解决方案DEVECO_SDK_HOMEInvaliddaemon 缓存旧环境变量--stop-daemon后重试build-profile.json5not found在错误目录执行 hvigorwcd 到项目根目录EPERM mkdir在工具目录下执行构建在项目目录执行Preferences 数据丢失未调flush()put 后显式调用 flush6.2 后续可扩展方向「知墨」目前是一个单机笔记应用如果需要继续迭代可以考虑数据云同步基于华为云AGConnect的云数据库实现多设备同步富文本编辑支持 Markdown 渲染图片附件使用kit.MediaLibraryKit访问相册Widget 卡片在桌面上展示最近笔记语音输入基于kit.VoiceCallKit的语音转文字分布式协同利用 HarmonyOS 分布式数据管理在多设备间流转七、系列总结五篇博文路线图第一篇环境搭建与项目初始化 ↓ DevEco Studio 安装、SDK 配置、hvigor 构建、项目结构 第二篇数据层与核心架构 ↓ Clean Architecture、领域模型、Repository、Preferences 第三篇UI组件与主页开发 ↓ CategoryBadge/StatsCard/NoteCard/EmptyState、主页面 第四篇多页面路由与交互 ↓ 详情页、编辑页、搜索页、路由机制、表单校验 第五篇主题切换与发布准备 ↓ 深色模式、设置页、签名、构建 HAP、项目总结学习收获通过「知墨」笔记应用的完整开发我们实践了✅ArkTS 语言interface、class、async/await、装饰器语法✅ArkUI 声明式框架Component、State、Prop、build() 链式调用✅页面路由router.pushUrl/back/getParams、页面注册✅数据持久化Preferences API、JSON 序列化✅组件化设计自定义组件拆分、Props 传递、回调函数✅主题管理AppStorage、setColorMode、资源覆盖机制✅构建发布hvigorw、签名配置、HAP 打包开发环境DevEco Studio 6.1 | HarmonyOS SDK 6.1.0 (API 23) | ArkTS ArkUI如果你对这个项目有任何问题或建议欢迎在评论区讨论