鸿蒙6.0应用开发——切换主题

张开发
2026/5/26 13:27:23 15 分钟阅读
鸿蒙6.0应用开发——切换主题
【高心星出品】文章目录鸿蒙6.0应用开发——主题换肤概述自定义主题色设置应用内组件自定义主题色设置应用局部页面自定义主题风格设置应用页面局部深浅色鸿蒙6.0应用开发——主题换肤概述对于采用ArkTS开发的应用提供了应用内组件的主题换肤功能支持局部的深浅色切换及动态换肤。目前该功能只支持设置应用内主题换肤暂不支持在UIAbility或窗口层面进行主题设置同时也不支持C-API和Node-API。自定义主题色当应用需要使用换肤功能时应自定义主题颜色。CustomTheme用于自定义主题色的内容其属性可选仅需对需要修改的token字段赋值其余token将继承系统默认颜色值可参考系统默认的token颜色值。请参照以下示例自定义主题色import { CustomColors, CustomTheme } from kit.ArkUI; export class AppColors implements CustomColors { // 自定义主题色 public brand: ResourceColor #FF75D9; // 使用$r让一级警示色在深色和浅色模式下设置为不同的颜色 public warning: ResourceColor $r(sys.color.ohos_id_color_warning); } export class AppTheme implements CustomTheme { public colors: AppColors new AppColors(); } export let gAppTheme: CustomTheme new AppTheme();代码逻辑走读导入CustomColors和CustomTheme接口这些接口可能定义了颜色和主题的结构和行为。定义AppColors类该类实现了CustomColors接口并定义了品牌色brand和警示色warning。品牌色直接设置为十六进制颜色值#FF75D9而警示色使用了系统资源$r(sys.color.ohos_id_color_warning)这表明在不同颜色模式下警示色会有不同的显示效果。定义AppTheme类该类实现了CustomTheme接口并实例化了AppColors类将其赋值给colors属性。定义了一个全局变量gAppTheme该变量是一个CustomTheme类型的实例使用了AppTheme类来初始化。设置应用内组件自定义主题色若在页面入口处设置应用内组件自定义主题色需确保在页面build前执行ThemeControl.setDefaultTheme。示例代码中onWillApplyTheme回调函数用于使自定义组件获取当前生效的Theme对象。// Index.ets import { Theme, ThemeControl } from kit.ArkUI; import { gAppTheme } from ./AppTheme; //在页面build前执行ThemeControl ThemeControl.setDefaultTheme(gAppTheme); Entry Component struct DisplayPage { State menuItemColor: ResourceColor $r(sys.color.background_primary); onWillApplyTheme(theme: Theme) { this.menuItemColor theme.colors.backgroundPrimary; } build() { Column() { List({ space: 10 }) { ListItem() { Column({ space: 5vp }) { Text(Color mode) .margin({ top: 5vp, left: 14fp }) .width(100%) Row() { Column() { Text(Light) .fontSize(16fp) .textAlign(TextAlign.Start) .alignSelf(ItemAlign.Center) Radio({ group: light or dark, value: light }) .checked(true) } .width(50%) Column() { Text(Dark) .fontSize(16fp) .textAlign(TextAlign.Start) .alignSelf(ItemAlign.Center) Radio({ group: light or dark, value: dark }) } .width(50%) } } .width(100%) .height(90vp) .borderRadius(10vp) .backgroundColor(this.menuItemColor) } ListItem() { Column() { Text(Brightness) .width(100%) .margin({ top: 5vp, left: 14fp }) Slider({ value: 40, max: 100 }) } .width(100%) .height(70vp) .borderRadius(10vp) .backgroundColor(this.menuItemColor) } ListItem() { Column() { Row() { Column({ space: 5vp }) { Text(Touch sensitivity) .fontSize(16fp) .textAlign(TextAlign.Start) .width(100%) Text(Increase the touch sensitivity of your screen for use with screen protectors) .fontSize(12fp) .fontColor(Color.Blue) .textAlign(TextAlign.Start) .width(100%) } .alignSelf(ItemAlign.Center) .margin({ left: 14fp }) .width(75%) Toggle({ type: ToggleType.Switch, isOn: true }) .margin({ right: 14fp }) .alignSelf(ItemAlign.Center) } .width(100%) .height(80vp) } .width(100%) .borderRadius(10vp) .backgroundColor(this.menuItemColor) } ListItem() { Column() { Text(Warning) .width(100%) .margin({ top: 5vp, left: 14fp }) Button(Text) .type(ButtonType.Capsule) .role(ButtonRole.ERROR) .width(40%) } .width(100%) .height(70vp) .borderRadius(10vp) .backgroundColor(this.menuItemColor) } } } .padding(10vp) .backgroundColor(#dcdcdc) .width(100%) .height(100%) } }代码逻辑走读导入模块导入了Theme和ThemeControl模块用于管理应用的主题。导入了gAppTheme这是一个应用主题的全局变量。设置默认主题在页面构建前通过ThemeControl.setDefaultTheme(gAppTheme)设置默认主题。定义组件DisplayPage使用Entry和Component装饰器定义了一个名为DisplayPage的组件。状态管理使用State装饰器定义了一个状态变量menuItemColor用于存储菜单项的颜色。主题响应定义了onWillApplyTheme方法当主题变化时更新menuItemColor以反映新的主题颜色。页面构建使用Column和List组件构建页面布局。每个ListItem包含不同的设置项如Text、Radio、Slider、Toggle和Button。每个设置项的样式和行为通过width、height、backgroundColor等属性进行设置。布局和样式使用Row和Column进行布局确保设置项在页面中的排列和样式符合设计要求。通过margin、padding、borderRadius等属性调整组件的间距和外观。交互逻辑Radio和Toggle组件允许用户进行选择和开关操作影响页面显示和行为。Slider组件用于调整亮度的设置响应用户的滑动操作。若在UIAbility中设置应用内组件自定义主题色需在onWindowStageCreate()方法的windowStage.loadContent的完成时回调中调用ThemeControl.setDefaultTheme设置应用内组件的自定义主题色。// EntryAbility.ets import {AbilityConstant, UIAbility, Want } from kit.AbilityKit; import { hilog } from kit.PerformanceAnalysisKit; import { window, CustomColors, ThemeControl } from kit.ArkUI; class AppColors implements CustomColors { fontPrimary 0xFFD53032; iconOnPrimary 0xFFD53032; iconFourth 0xFFD53032; } const abilityThemeColors new AppColors(); export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { hilog.info(0x0000, testTag, %{public}s, Ability onCreate); } onDestroy() { hilog.info(0x0000, testTag, %{public}s, Ability onDestroy); } onWindowStageCreate(windowStage: window.WindowStage) { // Main window is created, set main page for this ability hilog.info(0x0000, testTag, %{public}s, Ability onWindowStageCreate); windowStage.loadContent(pages/Index, (err, data) { if (err.code) { hilog.error(0x0000, testTag, Failed to load the content. Cause: %{public}s, JSON.stringify(err) ?? ); return; } hilog.info(0x0000, testTag, Succeeded in loading the content. Data: %{public}s, JSON.stringify(data) ?? ); // 在onWindowStageCreate()方法中setDefaultTheme ThemeControl.setDefaultTheme({ colors: abilityThemeColors }); hilog.info(0x0000, testTag, %{public}s, ThemeControl.setDefaultTheme done); }); } }代码逻辑走读导入模块代码首先导入了AbilityConstant,UIAbility,Want等模块这些模块提供了应用程序能力的基础功能和常量。定义自定义颜色AppColors类实现了CustomColors接口并定义了应用程序的主色调。初始化颜色主题创建了abilityThemeColors实例用于应用程序的主题颜色。定义EntryAbility类该类继承自UIAbility用于管理应用程序的生命周期。生命周期方法onCreate在能力创建时调用记录日志信息。生命周期方法onDestroy在能力销毁时调用记录日志信息。生命周期方法onWindowStageCreate在窗口阶段创建时调用加载主页面内容并设置默认主题颜色。日志记录使用hilog模块记录信息和错误日志以便于调试和监控应用程序的运行状态。说明当setDefaultTheme的参数为undefined时会清除先前设置的自定义主题默认token值对应的色值参考系统缺省token色值。setDefaultTheme需要在ArkUI初始化后即windowStage.loadContent的完成时回调中使用。设置应用局部页面自定义主题风格通过设置WithTheme将自定义主题Theme的配色应用于内部组件的默认样式。在WithTheme的作用范围内组件的配色会根据Theme的配色进行调整。说明在自定义节点BuilderNode中使用WithTheme为了确保显示效果正确需手动传递系统环境变化事件触发节点的全量更新详细请参考BuilderNode系统环境变化更新。如示例所示使用WithTheme({ theme: this.CustomTheme })可将作用域内组件的配色设置为自定义主题风格。后续可以通过更新this.CustomTheme来更换主题风格。onWillApplyTheme回调函数用于使自定义组件能够获取当前生效的Theme对象。import { CustomColors, CustomTheme, Theme } from kit.ArkUI; import { common } from kit.AbilityKit; //请将$r(app.color.xxx)替换为实际资源文件 class AppColors implements CustomColors { public fontPrimary: ResourceColor $r(app.color.brand_purple); public backgroundEmphasize: ResourceColor $r(app.color.brand_purple); } class AppColorsSec implements CustomColors { public fontPrimary: ResourceColor $r(app.color.brand); public backgroundEmphasize: ResourceColor $r(app.color.brand); } class AppTheme implements CustomTheme { public colors: AppColors new AppColors(); } class AppThemeSec implements CustomTheme { public colors: AppColors new AppColorsSec(); } Entry Component struct DisplayPage1 { State customTheme: CustomTheme new AppTheme(); // 请将$r(app.string.SetCustomThemeStyle)替换为实际资源文件在本示例中该资源文件的value值为设置应用局部页面自定义主题风格 State message: ResourceStr $r(app.string.SetCustomThemeStyle); count 0; build() { WithTheme({ theme: this.customTheme }) { Row(){ Column() { Text(WithTheme) .fontSize(30) .margin({bottom: 10}) Text(this.message) .margin({bottom: 10}) Button(change theme).onClick(() { this.count; if (this.count 1) { this.count 0; } switch (this.count) { case 0: this.customTheme new AppTheme(); break; case 1: this.customTheme new AppThemeSec(); break; default: break; } }) } .width(100%) } .height(100%) .width(100%) } } }代码逻辑走读导入模块从kit.ArkUI导入CustomColors,CustomTheme,Theme。从kit.AbilityKit导入common。定义颜色类创建AppColors类实现CustomColors接口定义fontPrimary和backgroundEmphasize颜色。创建AppColorsSec类实现CustomColors接口定义不同的fontPrimary和backgroundEmphasize颜色。定义主题类创建AppTheme类实现CustomTheme接口使用AppColors实例作为颜色。创建AppThemeSec类实现CustomTheme接口使用AppColorsSec实例作为颜色。定义组件使用Entry和Component装饰器定义DisplayPage1组件。使用State装饰器定义customTheme和message状态以及count变量。构建UI在build方法中使用WithTheme包裹Row组件。Row组件内包含一个Column其中有两个Text组件和一个Button组件。Button组件的点击事件用于切换主题通过this.count的值来决定切换到AppTheme还是AppThemeSec。主题切换逻辑当按钮被点击时this.count递增根据this.count的值在AppTheme和AppThemeSec之间切换。如果this.count超过1则重置为0以避免无限循环。设置应用页面局部深浅色通过WithTheme可以设置三种颜色模式跟随系统模式浅色模式和深色模式。在WithTheme的作用范围内组件的样式资源值会根据指定的模式读取对应的深浅色模式系统和应用资源值。这意味着在WithTheme作用范围内组件的配色会根据所指定的深浅模式进行调整。如下面的示例所示通过WithTheme({ colorMode: ThemeColorMode.DARK })可以将作用范围内的组件设置为深色模式。设置局部深浅色时需要添加dark.json资源文件深浅色模式才会生效。dark.json数据示例{color:[{name:start_window_background,value:#000000}]}import{ThemeControl}fromkit.ArkUI;ThemeControl.setDefaultTheme(undefined);EntryComponentstruct DisplayPage3{Statemessage:stringHello World;StatecolorMode:ThemeColorModeThemeColorMode.DARK;build(){WithTheme({colorMode:this.colorMode}){Row(){Column(){Text(this.message).fontSize(50).fontWeight(FontWeight.Bold)Button(Switch ColorMode).onClick((){if(this.colorModeThemeColorMode.LIGHT){this.colorModeThemeColorMode.DARK;}elseif(this.colorModeThemeColorMode.DARK){this.colorModeThemeColorMode.LIGHT;}})}.width(100%)}.backgroundColor($r(sys.color.background_primary)).height(100%).expandSafeArea([SafeAreaType.SYSTEM],[SafeAreaEdge.TOP,SafeAreaEdge.END,SafeAreaEdge.BOTTOM,SafeAreaEdge.START])}}}代码逻辑走读导入模块代码首先从kit.ArkUI库中导入了ThemeControl模块用于主题控制。设置默认主题调用ThemeControl.setDefaultTheme(undefined)设置默认主题。组件定义使用Entry和Component装饰器定义了一个名为DisplayPage3的组件。状态声明在组件中声明了两个状态变量message为字符串类型初始值为Hello WorldcolorMode为ThemeColorMode枚举类型初始值为亮色模式ThemeColorMode.LIGHT。界面构建 使用WithTheme上下文管理颜色模式。创建一个水平布局Row其中包含一个垂直布局Column。在Column中首先显示文本this.message字体大小为50字体加粗。然后显示一个按钮文本为Switch ColorMode点击按钮时根据当前的colorMode切换到相反的模式。设置布局的背景颜色、高度和安全区域。

更多文章