鸿蒙中 自定义主题色以及换肤
ArkTS框架支持应用内组件级别的主题换肤功能,包括自定义主题色和局部深浅色切换。开发者可通过CustomTheme接口定义主题色,使用ThemeControl.setDefaultTheme()全局应用,或通过WithTheme容器实现局部主题设置。系统提供预定义Token支持深浅色自动适配,但需注意不支持UIAbility/窗口级设置,且在BuilderNode中使用需手动更新。深色模式需准备
本文同步发表于 微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
ArkTS开发框架支持应用内组件的主题换肤功能,包括:
-
局部深浅色切换
-
动态换肤
-
自定义主题色
限制:
-
仅支持应用内组件级别设置,不支持UIAbility或窗口级别
-
不支持C-API和Node-API
二、自定义主题色
2.1 创建自定义主题类
使用 CustomTheme 和 CustomColors 接口定义自定义主题色,仅需覆盖需要修改的Token字段,未覆盖的字段继承系统默认值。
示例:自定义主题色
import { CustomColors, CustomTheme } from '@kit.ArkUI';
export class AppColors implements CustomColors {
// 自定义品牌色
public brand: ResourceColor = '#FF75D9';
// 使用系统资源,支持深浅色自动切换
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();
三、设置应用内组件自定义主题色
3.1 在页面入口处设置
需在页面 build() 前调用 ThemeControl.setDefaultTheme()。
示例:在Index.ets中设置
import { Theme, ThemeControl } from '@kit.ArkUI';
import { gAppTheme } from './AppTheme';
// 在页面build前设置默认主题
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')
}
.backgroundColor(this.menuItemColor)
}
// ... 其他列表项
}
}
}
}
3.2 在UIAbility中设置
在 onWindowStageCreate() 方法的 windowStage.loadContent 完成回调中设置主题。
示例:EntryAbility.ets
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
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 {
onWindowStageCreate(windowStage: window.WindowStage) {
windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
return;
}
// 在加载完成后设置主题
ThemeControl.setDefaultTheme({ colors: abilityThemeColors });
});
}
}
注意事项:
-
若
setDefaultTheme参数为undefined,则清除自定义主题,恢复系统默认 -
必须在ArkUI初始化后调用,即
windowStage.loadContent的完成回调中
四、设置应用局部页面自定义主题
4.1 使用WithTheme容器
通过 WithTheme 容器为局部范围应用自定义主题,支持动态切换主题。
示例:动态切换主题
import { CustomColors, CustomTheme, Theme } from '@kit.ArkUI';
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();
@State message: ResourceStr = $r('app.string.SetCustomThemeStyle');
count = 0;
build() {
WithTheme({ theme: this.customTheme }) {
Column() {
Text('WithTheme').fontSize(30)
Text(this.message)
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;
}
})
}
}
}
}
4.2 在BuilderNode中使用WithTheme
若在 BuilderNode 中使用 WithTheme,需手动传递系统环境变化事件以触发更新。
五、设置应用页面局部深浅色
5.1 使用WithTheme设置颜色模式
通过 WithTheme 的 colorMode 属性设置局部深浅色模式:
-
ThemeColorMode.SYSTEM:跟随系统 -
ThemeColorMode.LIGHT:固定浅色 -
ThemeColorMode.DARK:固定深色
示例:局部深浅色切换
import { ThemeControl, ThemeColorMode } from '@kit.ArkUI';
// 清除全局主题设置,确保局部设置生效
ThemeControl.setDefaultTheme(undefined);
@Entry
@Component
struct DisplayPage3 {
@State message: string = 'Hello World';
@State colorMode: ThemeColorMode = ThemeColorMode.DARK;
build() {
WithTheme({ colorMode: this.colorMode }) {
Column() {
Text(this.message)
Button('Switch ColorMode').onClick(() => {
if (this.colorMode === ThemeColorMode.LIGHT) {
this.colorMode = ThemeColorMode.DARK;
} else if (this.colorMode === ThemeColorMode.DARK) {
this.colorMode = ThemeColorMode.LIGHT;
}
})
}
.backgroundColor($r('sys.color.background_primary'))
}
}
}
5.2 深色模式资源准备
需在 resources/dark/element/ 目录下创建 dark.json 文件,定义深色资源。
示例:dark.json
{
"color": [
{
"name": "start_window_background",
"value": "#000000"
}
]
}
六、系统缺省Token色值
系统提供一系列预定义Token,支持深浅色自动切换。以下是部分关键Token的默认值:
| Token | 场景类别 | Light | Dark |
|---|---|---|---|
theme.colors.brand |
品牌色 | #ff0a59f7 |
#ff317af7 |
theme.colors.warning |
一级警示色 | #ffe84026 |
#ffd94838 |
theme.colors.fontPrimary |
一级文本 | #e5000000 |
#e5ffffff |
theme.colors.fontSecondary |
二级文本 | #99000000 |
#99ffffff |
theme.colors.backgroundPrimary |
一级背景 | #ffffffff |
#ffe5e5e5 |
theme.colors.backgroundSecondary |
二级背景 | #fff1f3f5 |
#ff191a1c |
theme.colors.iconPrimary |
一级图标 | #e5000000 |
#e5ffffff |
theme.colors.interactiveHover |
悬停交互色 | #0c000000 |
#0cffffff |
theme.colors.interactivePressed |
按压交互色 | #19000000 |
#19ffffff |
备注:完整Token列表参考官方文档中的表格。
总结
-
主题换肤支持:ArkTS支持应用内组件级别的主题换肤,包括自定义主题色和局部深浅色设置。
-
自定义主题:通过
CustomTheme和CustomColors定义,使用ThemeControl.setDefaultTheme()全局应用。 -
局部主题:使用
WithTheme容器实现局部主题或深浅色设置,支持动态切换。 -
系统Token:系统提供丰富的预定义Token,支持深浅色自动适配。
-
注意事项:
-
不支持UIAbility/窗口级主题设置
-
在BuilderNode中使用需手动更新
-
深色模式需准备对应的资源文件
-
更多推荐


所有评论(0)