【经验分享】鸿蒙如何实现自定义 App 样式主题
在移动应用开发中,样式主题的设计是提升用户体验的重要环节。一个灵活且美观的主题系统,不仅能让应用更具吸引力,还能满足用户的个性化需求。鸿蒙操作系统(HarmonyOS)作为国产操作系统的代表,提供了强大的 UI 开发能力,尤其是 ArkUI 框架和 ArkTS 语言,让开发者能够轻松实现自定义样式主题。
本文将详细介绍如何在鸿蒙开发中实现自定义 App 样式主题,涵盖从基础概念到具体实现的完整流程。无论你是鸿蒙开发的新手,还是有一定经验的前端开发者,都能从中获得实用的技术参考。
1. 什么是样式主题?
样式主题是指应用中统一的视觉风格,包括颜色、字体、间距等 UI 元素的定义。通过主题系统,开发者可以:
- 统一管理 UI 样式:避免重复定义样式,提高代码可维护性。
- 动态切换主题:支持白天/黑夜模式切换,或用户自定义主题。
- 提升用户体验:通过个性化的视觉设计,增强用户对应用的认同感。
2. 实现自定义样式主题的步骤
-
定义样式类,方便定制多个样式(举个简单例子):
export class BaseVar { private _RBackground = "#f7f8fa"; private _RRed = "#ee0a24"; private _RBlue = "#1989fa"; private _ROrange = "#ff976a"; private _RGreen = "#07c160"; private _RPrimaryColor = this._RBlue; private _RSuccessColor = this._RGreen; private _RDangerColor = this._RRed; private _RWarningColor = this._ROrange; get RBackground() { return this._RBackground; } set RBackground(value: string) { this._RBackground = value; } setRBackground(value: string) { this._RBackground = value; return this; } get RRed() { return this._RRed; } set RRed(value: string) { this._RRed = value; this.setRDangerColor(value); } setRRed(value: string) { this._RRed = value; this.setRDangerColor(value); return this; } get RBlue() { return this._RBlue; } set RBlue(value: string) { this._RBlue = value; this.setRPrimaryColor(value); } setRBlue(value: string) { this._RBlue = value; this.setRPrimaryColor(value); return this; } get ROrange() { return this._ROrange; } set ROrange(value: string) { this._ROrange = value; this.setRWarningColor(value); } setROrange(value: string) { this._ROrange = value; this.setRWarningColor(value); return this; } get RGreen() { return this._RGreen; } set RGreen(value: string) { this._RGreen = value; this.setRSuccessColor(value); } setRGreen(value: string) { this._RGreen = value; this.setRSuccessColor(value); return this; } get RPrimaryColor() { return this._RPrimaryColor; } set RPrimaryColor(value: string) { this._RPrimaryColor = value; } setRPrimaryColor(value: string) { this._RPrimaryColor = value; return this; } get RSuccessColor() { return this._RSuccessColor; } set RSuccessColor(value: string) { this._RSuccessColor = value; } setRSuccessColor(value: string) { this._RSuccessColor = value; return this; } get RDangerColor() { return this._RDangerColor; } set RDangerColor(value: string) { this._RDangerColor = value; } setRDangerColor(value: string) { this._RDangerColor = value; return this; } get RWarningColor() { return this._RWarningColor; } set RWarningColor(value: string) { this._RWarningColor = value; } setRWarningColor(value: string) { this._RWarningColor = value; return this; } } -
实例化样式类,生成主题样式数据(可通过内部方法链式设置其属性值):
export const lightBaseVar = new BaseVar(); export const darkBaseVar = new BaseVar() .setRBlue("#0000ff") .setRGreen("#00ff00"); -
封装一个主题类,并导出主题类的实例:
import { BaseVar } from "./const/base"; import { lightBaseVar, darkBaseVar } from "./init/base"; export class Theme { themes: Map<string, BaseVar> = new Map(); themeName: string = ""; constructor(themes?: Map<string, BaseVar>, themeName?: string) { if (themes) this.themes = themes; if (themeName) this.themeName = themeName; } add(themeName: string, theme: BaseVar) { this.themes.set(themeName, theme); return this; } set(themeName: string) { this.themeName = themeName; return this; } get() { return this.themes.get(this.themeName); } keys() { return this.themes.keys(); } has(themeName: string) { return this.themes.has(themeName); } del(themeName: string) { if (this.has(themeName)) { this.themes.delete(themeName); } return this; } } export const theme = new Theme() .add("light", lightBaseVar) .add("dark", darkBaseVar) .set("light");至此,主题的就封装完毕。那么该如何使用呢?
3. 如何使用自定义主题
首先使用的时候,需要导入上面的theme ,然后如果需要修改主题直接调用set方法,如果需要新增主题,只需要实例化BaseVar类手动设置内部变量的值(可通过set方法修改 或 set[属性名]方法链式调用进行修改),再通过add 方法新增即可。下面举个组件使用的例子:
-
定义一个
RConfigProvider组件。import {theme} from '../../theme/index' import {BaseVar} from '../../theme/const/base' export class RConfigProviderModifier implements AttributeModifier<ColumnAttribute>{ private backgroundColor:string='' private height:string|number = '100%' private width:string|number='100%' private useTheme:BaseVar|undefined = theme.get() setBackgroundColor(backgroundColor:string):RConfigProviderModifier{ this.backgroundColor = backgroundColor return this } setHeight(height:string|number):RConfigProviderModifier{ this.height = height return this } setWidth(width:string|number):RConfigProviderModifier{ this.width = width return this } setTheme(useTheme:BaseVar|undefined):RConfigProviderModifier{ this.useTheme = useTheme return this } applyNormalAttribute(instance: ColumnAttribute): void { if(this.backgroundColor!=null){ instance.backgroundColor(this.backgroundColor) }else if(this.useTheme!=undefined){ instance.backgroundColor(this.useTheme.RBackground) } instance.width(this.width) instance.height(this.height) } } @Component export struct RConfigProvider{ @Prop modifier: RConfigProviderModifier | null = null; @Builder customBuilder() {}; @BuilderParam customBuilderParam: () => void = this.customBuilder; @Prop @Watch("onThemeChange") themeName:string = 'light' @State isRender:number = 0 aboutToAppear(){ if(!this.modifier){ this.modifier = new RConfigProviderModifier() theme.set(this.themeName) this.modifier.setTheme(theme.get()) } } onThemeChange(){ this.isRender = this.isRender+1 theme.set(this.themeName) if(this.modifier!=null){ this.modifier.setTheme(theme.get()) } } build() { Column() { if(this.isRender % 2){ this.customBuilderParam() }else{ this.customBuilderParam() } } .attributeModifier(this.modifier) } } 其核心就是外层维护使用的主题
themeName,当其变化后,重新渲染内部组件(已更新使用了的主题样式的组件,内部组件应在创建时使用theme.get()获取最新主题) -
使用
RConfigProvider组件import {theme} from '../../theme/index' @Entry @Component struct Index{ @State themeName: string = 'light'; @Builder customContentBuilder(){ //此处放置使用了theme主题的样式的组件 } build() { Column() { RConfigProvider( { themeName: this.themeName, customBuilderParam:this.componentBuilder } ) } .height('100%') .width('100%') } }可在这个页面修改
themeName值,组件内会自动同步重新渲染内部,达成组件样式切换。
4. 实践建议
- 统一管理主题变量:将主题变量集中管理,便于维护和扩展。
- 支持用户自定义主题:允许用户选择或自定义主题,提升用户体验。
- 优化性能:避免频繁切换主题导致的性能问题,合理使用状态管理。
5. 总结
通过鸿蒙的 ArkUI 框架和 ArkTS 语言,开发者可以轻松实现自定义 App 样式主题。使用主题样式,都能为应用增添更多的灵活性和个性化。
这是题主使用的一种自定义主题样式的方案,更多可参考完整示例。
希望这个封装思路能够帮助到大家,也可以动动小手指,给作者点个小星星~