在Harmony开发中,主题系统是构建个性化用户体验的重要组成部分。本文将通过代码示例,详细介绍如何基于原生能力实现应用主题的全局设置与局部切换,包括自定义主题颜色、深浅色模式适配等核心功能。
一、全局主题设置
1. 自定义主题颜色
通过CustomColors
接口定义主题颜色资源,开发者可以灵活控制应用的整体视觉风格。
// AppColors.ets
import { CustomColors, ResourceColor } from '@ohos.arkui.theme'
export class AppColors implements CustomColors {
fontPrimary: ResourceColor = '#6A3E80' // 主文本颜色
fontOnPrimary: ResourceColor = '#FDECFF' // 主背景上的文本颜色
iconOnPrimary: ResourceColor = '#FDECFF' // 主背景上的图标颜色
compBackgroundPrimary: ResourceColor = '#FFF1FB' // 主要组件背景色
backgroundEmphasize: ResourceColor = '#FF75D9' // 强调背景色
}
2. 在Ability中设置全局主题
通过ThemeControl.setDefaultTheme()
方法,在应用启动时加载自定义主题。
// EntryAbility.ets
import { UIAbility, WindowStage } from '@kit.AbilityKit'
import { hilog } from '@kit.PerformanceAnalysisKit'
import { ThemeControl, CustomTheme } from '@ohos.arkui.theme'
import { AppColors } from './AppColors'
export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage: WindowStage) {
windowStage.loadContent('pages/Index', (err, data) => {
if (err) {
hilog.error(0x0000, 'ThemeDemo', `Failed to load content: ${JSON.stringify(err)}`)
return
}
// 创建自定义主题对象
const customTheme: CustomTheme = {
colors: new AppColors()
}
// 应用全局主题
ThemeControl.setDefaultTheme(customTheme)
hilog.info(0x0000, 'ThemeDemo', 'Global theme applied successfully')
})
}
}
二、局部主题切换
1. 定义多套主题
通过创建不同的CustomTheme
实例,实现多主题配置。
// Themes.ets
import { CustomTheme, CustomColors, ResourceColor } from '@ohos.arkui.theme'
// 默认主题
export class DefaultTheme implements CustomTheme {
colors = new (class DefaultColors implements CustomColors {
fontPrimary = '#1E90FF' // 蓝色主题
backgroundPrimary = '#F0F8FF'
})()
}
// 暗色主题
export class DarkTheme implements CustomTheme {
colors = new (class DarkColors implements CustomColors {
fontPrimary = '#FFFFFF' // 白色文本
backgroundPrimary = '#121212' // 黑色背景
})()
}
2. 页面内动态切换主题
使用WithTheme
组件包裹需要应用主题的区域,并通过状态管理切换主题。
// ThemeSwitchPage.ets
import { WithTheme, CustomTheme } from '@ohos.arkui.theme'
import { promptAction } from '@kit.ArkUI'
import { DefaultTheme, DarkTheme } from './Themes'
@Entry
@Component
struct ThemeSwitchPage {
@State currentTheme: CustomTheme = new DefaultTheme()
@State isDarkMode: boolean = false
build() {
WithTheme({ theme: this.currentTheme }) {
Column() {
Button(this.isDarkMode ? '切换为默认主题' : '切换为暗色主题')
.onClick(() => {
this.isDarkMode = !this.isDarkMode
this.currentTheme = this.isDarkMode ? new DarkTheme() : new DefaultTheme()
promptAction.showToast({
message: this.isDarkMode ? '已启用暗色主题' : '已启用默认主题',
duration: 1000
})
})
.margin(20)
.fontSize(20)
Text('主题切换示例')
.fontSize(30)
.fontWeight(FontWeight.Bold)
.padding(20)
}
.width('100%')
.height('100%')
.backgroundColor(this.currentTheme.colors.backgroundPrimary)
}
}
}
三、深浅色模式适配
1. 设置深浅色模式
通过WithTheme
组件的colorMode
属性,控制组件的深浅色模式。
// ColorModePage.ets
import { WithTheme, ThemeColorMode } from '@ohos.arkui.theme'
@Entry
@Component
struct ColorModePage {
@State colorMode: ThemeColorMode = ThemeColorMode.SYSTEM
build() {
WithTheme({
theme: new DefaultTheme(),
colorMode: this.colorMode
}) {
Column() {
Button('切换深浅色模式')
.onClick(() => {
this.colorMode =
this.colorMode === ThemeColorMode.DARK
? ThemeColorMode.LIGHT
: ThemeColorMode.DARK
})
.margin(20)
.fontSize(20)
Text('深浅色适配示例')
.fontSize(28)
.padding(20)
}
.width('100%')
.height('100%')
}
}
}
四、完整主题资源管理
1. 颜色资源文件
在resources/base/element/color.json
中定义基础颜色资源:
{
"color": [
{
"name": "primary_color",
"value": "#FF3B99FC"
},
{
"name": "secondary_color",
"value": "#FF007DFF"
}
]
}
2. 深色模式资源
在resources/dark/element/color.json
中定义深色模式颜色:
{
"color": [
{
"name": "primary_color",
"value": "#FF1E90FF"
},
{
"name": "secondary_color",
"value": "#FF000080"
}
]
}
五、总结
通过鸿蒙的ThemeControl
和WithTheme
能力,开发者可以轻松实现:
- 全局主题:在Ability中统一设置应用主题
- 局部主题:在特定页面或组件中动态切换主题
- 深浅色适配:自动跟随系统或手动切换深浅色模式
- 资源管理:通过
color.json
文件管理不同模式下的颜色资源
注意事项:
- 全局主题应在
onWindowStageCreate
生命周期中设置 - 局部主题切换需通过
@State
状态管理驱动UI更新 - 深浅色适配建议优先使用系统预置资源(如
$r('sys.color.ohos_id_color_text_primary')
)
通过合理使用主题系统,开发者可以为用户提供更丰富的视觉体验和个性化选择。