HarmonyOS鸿蒙Next中多主题颜色资源文件如何切换引用
HarmonyOS鸿蒙Next中多主题颜色资源文件如何切换引用 客户需要做多种颜色主题,并且每种主题都有一个color.json文件,如何在切换主题时切换引入不同的color.json 大概有8个这样的文件。
在resources
目录下为每个主题创建独立子目录(如theme1
、theme2
),每个目录中放置对应的color.json
:
resources/
├── theme1/
│ └── element/
│ └── `color`.json
├── theme2/
│ └── element/
│ └── `color`.json
所有主题的color.json
中需保持相同颜色ID定义,仅改变色值:
// theme1/`color`.json
{
"color": [
{ "name": "primary_color", "value": "#FF0000" }
]
}
// theme2/`color`.json
{
"color": [
{ "name": "primary_color", "value": "#00FF00" }
]
}
创建全局状态管理类存储当前主题标识:
class ThemeManager {
private currentTheme: string = 'theme1';
setTheme(themeName: string) {
this.currentTheme = themeName;
// 触发界面重绘逻辑
}
}
通过字符串拼接方式动态加载对应主题资源:
function getDynamicColor(resName: string) {
const themePath = `app.${ThemeManager.currentTheme}.color.${resName}`;
return $r(themePath);
}
// 使用示例
Text('主题文字')
.fontColor(getDynamicColor('primary_color'))
更多关于HarmonyOS鸿蒙Next中多主题颜色资源文件如何切换引用的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
这种方式依赖于切换流程中重新执行属性设置代码,随着系统的发展和性能优化,并不能确保所有属性代码均被重新执行。因为在大部分热更新场景中,重新执行全部页面构建和属性设置代码显然是冗余的。
我都觉得这都是最优解了,但是不知道为什么官方不推荐 https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ui-dark-light-color-adaptation#
一楼的方法可以借鉴参考的,我们内部实现主体切换也是这种思路,也可以参考官方的主体切换,参考文档:ThemeControl,WithTheme-主题-ArkTS组件-ArkUI(方舟UI框架)-应用框架 - 华为HarmonyOS开发者。
class AppColors implements CustomColors { fontPrimary: ResourceColor = $r(‘sys.color.font_primary’) brand: ResourceColor = $r(‘sys.color.brand’)
/**
- other Colors */ }
class AppTheme implements CustomTheme { public colors: AppColors = new AppColors(); }
@Entry @Component struct DisplayPage { arr = [‘color1.json’,/…/‘color8.json’] @State customTheme: CustomTheme = new AppTheme();
build() { WithTheme({ theme: this.customTheme }) {
Column() {
Text('WithTheme')
.fontSize(30)
.margin({ bottom: 10 })
ForEach(this.arr,(item:string)){
Button(item).onClick(() => {
this.changeColor(item)
})
}
}
.height('100%')
.width('100%')
.backgroundColor(this.customTheme.colors!.backgroundPrimary)
}
}
async changeColor(colorJsonFileName: string) { const data: Uint8Array | void = await this.getUIContext().getHostContext()?.resourceManager.getRawFileContent(colorJsonFileName) if (data) { const jsonStr = util.TextDecoder.create(“utf-8”, { ignoreBOM: true }).decodeToString(new Uint8Array(data.buffer)); const jsonObj = JSON.parse(jsonStr) const theme = new AppTheme() theme.colors.fontPrimary = Object(jsonObj)[‘font_primary’] theme.colors.brand = Object(jsonObj)[‘brand’] /** * other Colors */ this.customTheme = theme } } }
这8个color.json可以放raw里面,点击切换读取对应的color.json解析json然后把颜色值赋值给CustomColors。
系统多主题的设置方式参考以下文档:
通过class类实现定义不同的颜色, 同时根据appstorage决定加载哪个色系的class, 应该是可以实现的. 但这个例子颜色都是直接定义在ets文件中, 不知道能不能从color.js中读取.
在HarmonyOS Next中,可通过theme
模块实现多主题颜色资源切换。步骤如下:
-
在
resources/base/theme
目录下定义不同主题的json文件(如dark.json
/light.json
),包含颜色资源ID和对应值。 -
在代码中使用
this.context.resourceManager.getTheme
获取主题管理器,调用setTheme(id)
切换主题(id对应主题json文件名)。 -
在布局中直接引用主题颜色资源ID(如
$color:primary_color
),系统会自动根据当前主题切换实际颜色值。
注意:主题切换后需手动刷新UI,调用this.context.resourceManager.updateConfiguration
触发资源更新。
在HarmonyOS Next中实现多主题颜色资源切换,可以通过以下方式实现:
- 资源文件组织:
- 在resources目录下按主题分类存放color.json文件
- 例如:resources/theme1/color.json、resources/theme2/color.json等
- 动态切换实现:
// 获取当前资源管理器
let resourceManager = getContext().resourceManager;
// 设置主题路径
async function setTheme(themeName: string) {
try {
// 先清除当前主题
resourceManager.release();
// 加载新主题资源
await resourceManager.load("/resources/" + themeName);
} catch (err) {
console.error(`切换主题失败: ${err}`);
}
}
// 使用示例
setTheme("theme1");
- 资源引用: 切换后可以直接通过资源ID引用,系统会自动使用当前主题下的颜色值
$r('app.color.primary_color')
- 注意事项:
- 确保各主题下的color.json中定义的资源ID保持一致
- 主题切换可能需要重新渲染UI组件以生效
- 考虑将当前主题设置持久化存储
这种方法可以实现运行时动态切换主题,无需重新启动应用。