HarmonyOS NEXT ohos.arkui.theme 主题换肤完整使用指南关键词CustomTheme、CustomColors、ThemeControl、onWillApplyTheme、主题换肤效果一、概述ohos.arkui.theme是 HarmonyOS 提供的应用级主题换肤模块它允许开发者自定义应用的品牌色、字体色、组件背景色等视觉风格并实现一键切换主题的能力。1.1 核心能力能力说明自定义品牌色通过CustomColors覆盖系统默认 token 色值应用级主题切换通过ThemeControl.setDefaultTheme()全局生效组件感知主题变化onWillApplyTheme()生命周期回调获取当前主题深浅色主题通过colorsdarkColors分别定义浅色/深色配色1.2 核心类型一览CustomColors → 定义具体颜色值brand, fontPrimary, backgroundPrimary 等 CustomTheme → 主题对象包含 colors浅色和 darkColors深色 ThemeControl → 主题控制器用于设置/切换全局主题 Theme → 当前生效的主题对象只读在 onWillApplyTheme 中获取二、环境准备2.1 项目要求DevEco Studio 6.1 (Release)HarmonyOS NEXT SDK (API 23)项目compileSdkVersion≥ 232.2 导入方式// 方式一从 kit.ArkUI 导入推荐import{CustomColors,CustomTheme,ThemeControl,Theme}fromkit.ArkUI// 方式二从 ohos.arkui.theme 导入import{CustomColors,CustomTheme,ThemeControl,Theme}fromohos.arkui.theme兼容性提示ThemeColorMode枚举在某些 SDK 版本如 HarmonyOS SDK 6.1.x的kit.ArkUI中可能未导出。如果编译报错Module has no exported member ThemeColorMode请改用自定义状态管理深浅色模式参考 WithTheme 指南的兼容性方案。两种方式功能完全一致kit.ArkUI是 Kit 统一入口推荐优先使用。三、自定义主题颜色3.1 理解系统 Token 色值HarmonyOS 系统内置了一套完整的颜色 Token每个 Token 控制 UI 的不同部分。以下是常用 TokenToken 名称对应系统颜色作用brandsys.color.brand品牌色影响 Button 默认背景、Slider 选中色等fontPrimarysys.color.font_primary主文本颜色fontEmphasizesys.color.font_emphasize强调文本颜色fontOnPrimarysys.color.font_on_primary品牌色上的文本颜色backgroundPrimarysys.color.background_primary主背景色backgroundEmphasizesys.color.background_emphasize强调背景色compBackgroundPrimarysys.color.comp_background_primary组件默认背景compBackgroundEmphasizesys.color.comp_background_emphasize组件强调背景compDividersys.color.comp_divider分割线颜色关键规则你只需要覆盖想要修改的 Token未修改的部分自动继承系统默认值。3.2 实现 CustomColorsimport{CustomColors}fromkit.ArkUI// 定义浅色模式颜色exportclassMyColorsimplementsCustomColors{brand:ResourceColor#FF75D9// 品牌色粉色fontPrimary:ResourceColor#FF182431// 主文本色fontOnPrimary:ResourceColor#FFFFFFFF// 品牌色上的文字白色backgroundPrimary:ResourceColor#FFF5F5F5// 背景色compDivider:ResourceColor#1AFF75D9// 分割线半透明品牌色}3.3 实现 CustomThemeimport{CustomTheme}fromkit.ArkUI// 定义深色模式颜色exportclassMyDarkColorsimplementsCustomColors{brand:ResourceColor#FF99E6fontPrimary:ResourceColor#FFE6FFFFFFfontOnPrimary:ResourceColor#FF1A1A1AbackgroundPrimary:ResourceColor#FF1A1A1AcompDivider:ResourceColor#1AFF99E6}// 组合浅色 深色为完整主题exportclassMyThemeimplementsCustomTheme{colors:MyColorsnewMyColors()darkColors:MyDarkColorsnewMyDarkColors()}// 导出主题实例exportconstmyTheme:CustomThemenewMyTheme()提示如果不需要深色模式适配可以只实现colors省略darkColors。四、应用主题4.1 方式一应用级全局主题ThemeControlThemeControl.setDefaultTheme()在页面 build 之前执行可以设置整个应用的默认主题。import{ThemeControl}fromkit.ArkUIimport{myTheme}from./MyTheme// 在模块顶层执行确保在页面 build 前生效ThemeControl.setDefaultTheme(myTheme)EntryComponentstruct MainPage{build(){Column(){// 所有子组件自动应用 myTheme 的配色Button(品牌色按钮)// 按钮背景自动使用 brand 色Slider({value:50})// 滑块已加载部分使用 brand 色Checkbox()// 选中态使用 brand 色}}}关键要点setDefaultTheme()必须在模块顶层执行不在函数内调用后应用内所有组件的默认配色都会跟随自定义主题可以多次调用来动态切换全局主题4.2 方式二动态切换主题import{ThemeControl}fromkit.ArkUIEntryComponentstruct ThemeSwitchPage{StatethemeIndex:number0build(){Column({space:20}){Button(切换主题).onClick((){this.themeIndex(this.themeIndex1)%3switch(this.themeIndex){case0:ThemeControl.setDefaultTheme(defaultTheme)breakcase1:ThemeControl.setDefaultTheme(pinkTheme)breakcase2:ThemeControl.setDefaultTheme(greenTheme)break}})// 切换后所有组件自动更新Button(主按钮)Slider({value:60})}}}五、感知主题变化5.1 onWillApplyTheme 回调当主题发生变化时通过ThemeControl或WithTheme切换组件的onWillApplyTheme()生命周期会被调用。EntryComponentstruct ThemeAwarePage{StatebrandColor:ResourceColor$r(sys.color.brand)StatebgColor:ResourceColor$r(sys.color.background_primary)// 在 build() 之前执行可获取当前生效的主题对象onWillApplyTheme(theme:Theme){// theme.colors 包含了当前主题的所有颜色值this.brandColortheme.colors.brandthis.bgColortheme.colors.backgroundPrimary}build(){Column(){Text(主题感知文本).fontColor(this.brandColor)Button(品牌色按钮).backgroundColor(this.brandColor)}.backgroundColor(this.bgColor)}}5.2 Theme 对象结构interfaceTheme{colors:ReadonlyCustomColors// 当前生效的颜色只读}theme.colors中可以访问所有 Token 颜色值onWillApplyTheme(theme:Theme){// 常用颜色访问letbrandtheme.colors.brandletfonttheme.colors.fontPrimaryletbgtheme.colors.backgroundPrimaryletdividertheme.colors.compDivider// ... 更多 Token}六、完整示例多主题切换应用以下是一个完整的多主题切换示例包含 3 种自定义主题和动态切换功能。6.1 主题定义文件MyThemes.etsimport{CustomColors,CustomTheme}fromkit.ArkUI// 主题一樱花粉 classSakuraColorsimplementsCustomColors{brand:ResourceColor#FFFF7EB3fontPrimary:ResourceColor#FF2D1B2EfontOnPrimary:ResourceColor#FFFFFFFFbackgroundPrimary:ResourceColor#FFFFF0F5compDivider:ResourceColor#20FF7EB3}classSakuraDarkColorsimplementsCustomColors{brand:ResourceColor#FFFF5E9EfontPrimary:ResourceColor#FFFFF0F5fontOnPrimary:ResourceColor#FF2D1B2EbackgroundPrimary:ResourceColor#FF1A0F18compDivider:ResourceColor#20FF5E9E}classSakuraThemeimplementsCustomTheme{colors:SakuraColorsnewSakuraColors()darkColors:SakuraDarkColorsnewSakuraDarkColors()}// 主题二森林绿 classForestColorsimplementsCustomColors{brand:ResourceColor#FF4CAF50fontPrimary:ResourceColor#FF1B2D1BfontOnPrimary:ResourceColor#FFFFFFFFbackgroundPrimary:ResourceColor#FFF0FFF0compDivider:ResourceColor#204CAF50}classForestThemeimplementsCustomTheme{colors:ForestColorsnewForestColors()}// 主题三系统默认 classDefaultThemeimplementsCustomTheme{}// 导出主题实例 exportconstsakuraTheme:CustomThemenewSakuraTheme()exportconstforestTheme:CustomThemenewForestTheme()exportconstdefaultTheme:CustomThemenewDefaultTheme()6.2 主页面ThemeSwitchDemo.etsimport{Theme,ThemeControl}fromkit.ArkUIimport{sakuraTheme,forestTheme,defaultTheme}from./MyThemes// 设置初始默认主题ThemeControl.setDefaultTheme(defaultTheme)EntryComponentstruct ThemeSwitchDemo{StatecurrentBrand:ResourceColor$r(sys.color.brand)StatecurrentBg:ResourceColor$r(sys.color.background_primary)themeList:{name:string;theme:CustomTheme}[][{name:系统默认,theme:defaultTheme},{name:樱花粉,theme:sakuraTheme},{name:森林绿,theme:forestTheme}]StateselectedIndex:number0onWillApplyTheme(theme:Theme){this.currentBrandtheme.colors.brandthis.currentBgtheme.colors.backgroundPrimary}build(){Column({space:24}){Text(主题换肤演示).fontSize(24).fontWeight(FontWeight.Bold).fontColor(this.currentBrand)// 主题选择区域Row({space:16}){ForEach(this.themeList,(item:{name:string;theme:CustomTheme},index:number){Column({space:8}){Circle().width(48).height(48).fill(index0?#FF0A59F7:(index1?#FFFF7EB3:#FF4CAF50)).shadow({radius:this.selectedIndexindex?12:0,color:this.selectedIndexindex?#40000000:#00000000})Text(item.name).fontSize(12).fontColor(this.selectedIndexindex?this.currentBrand:#80000000)}.onClick((){this.selectedIndexindex ThemeControl.setDefaultTheme(item.theme)})},(item:{name:string},index:number)item.name)}.justifyContent(FlexAlign.Center).width(100%)// 展示受主题影响的组件Column({space:16}){Button(品牌色按钮).buttonStyle(ButtonStyleMode.EMPHASIZED)Slider({value:50,max:100}).width(80%)Checkbox()Toggle({type:ToggleType.Switch,isOn:true})}.padding(24).borderRadius(16).backgroundColor(this.currentBg)}.width(100%).height(100%).justifyContent(FlexAlign.Center).backgroundColor($r(sys.color.background_primary))}}6.3 运行效果说明操作效果点击樱花粉按钮背景变粉色文本变粉色背景变浅粉点击森林绿按钮背景变绿色文本变绿色背景变浅绿点击系统默认恢复系统默认蓝色主题切换系统深浅色有darkColors的主题自动适配深色配色七、最佳实践7.1 主题文件组织ets/ ├── theme/ │ ├── ThemeColors.ets # 颜色定义 │ ├── ThemeConfig.ets # 主题配置导出 │ └── ThemeManager.ets # 主题管理可选 ├── pages/ │ └── MainPage.ets7.2 注意事项规则说明只覆盖需要修改的 Token未修改的部分继承系统默认值减少维护成本setDefaultTheme()放在模块顶层确保在页面 build 之前执行始终提供darkColors系统深色模式下如果没有darkColors会使用默认深色值使用$r(sys.color.*)引用系统色让组件自动跟随主题变化配合WithTheme做局部主题全局用ThemeControl局部用WithTheme7.3 主题与 WithTheme 的关系ThemeControl.setDefaultTheme() → 影响整个应用全局 WithTheme({ theme: xxx }) → 只影响子组件局部 onWillApplyTheme() → 两种切换方式都会触发八、常见问题Q1调用 setDefaultTheme 后界面没变化A确保setDefaultTheme()在模块顶层执行不在函数内部执行。如果在onClick等事件回调中切换主题需要传入新的主题实例。Q2深色模式下颜色没变A需要在CustomTheme中实现darkColors属性。同时如果使用$r(app.color.xxx)自定义颜色需要在resources/dark/element/color.json中定义深色模式的颜色值。Q3如何获取当前主题的某个颜色值用于自定义组件A使用onWillApplyTheme(theme: Theme)回调通过theme.colors.xxx获取。九、总结ohos.arkui.theme提供了完整的应用级主题换肤能力定义主题实现CustomColorsCustomTheme接口应用主题ThemeControl.setDefaultTheme()全局生效感知变化onWillApplyTheme()获取当前主题颜色深浅适配通过colorsdarkColors分别定义掌握这些核心概念后配合WithTheme组件可以实现更精细的局部主题控制打造品牌一致性的 UI 体验。参考文档官方 APIohos.arkui.theme主题皮肤开发指南WithTheme 容器组件