HarmonyOS7 主题与深色模式:一套换肤方案实战
文章目录前言反模式颜色写死代码实现方案一AppStorage 集中存主题核心代码组件读取主题切换主题只改一处方案二Provider/Consumer组件树内完整示例结合系统深色模式代码解析常见误区小白必踩完整可运行示例深色模式换肤实现拆解写在最后前言现在的 app 基本都支持深色模式和换主题色。用户晚上刷手机不被亮瞎眼品牌也能用主题色强化识别。HarmonyOS 做主题切换不难关键是别到处写死颜色。这篇文章我讲一套集中管理主题的方案让你切深色模式只要改一个变量。反模式颜色写死新手最容易这样写代码实现Text(标题).fontColor(#333333)// 深色写死.backgroundColor(#FFFFFF)// 浅色写死问题要切深色模式得改每一个组件——几百个地方不可能。所以颜色必须引用变量不能写死字面值。方案一AppStorage 集中存主题用一个全局主题对象所有组件都读它核心代码// 定义主题interfaceTheme{bg:stringtext:stringprimary:string}constLight:Theme{bg:#FFFFFF,text:#333333,primary:#4A90E2}constDark:Theme{bg:#1A1A1A,text:#EEEEEE,primary:#4A90E2}// 存进全局AppStorage.setOrCreate(theme,Light)AppStorage是跨组件共享的全局存储存一个theme对象谁都能读。组件读取主题ComponentV2struct MyPage{StorageProp(theme)theme:ThemeLight// 订阅全局主题build(){Column(){Text(标题).fontColor(this.theme.text)Button(按钮).backgroundColor(this.theme.primary)}.backgroundColor(this.theme.bg).width(100%).height(100%)}}StorageProp(theme)订阅AppStorage里的theme它一变组件自动重绘。所有颜色都从this.theme.xxx取不再出现字面值。切换主题只改一处functiontoggleDark(){constcurAppStorage.get(theme)AppStorage.set(theme,curDark?Light:Dark)}切换时只改AppStorage里的theme所有用StorageProp订阅的组件瞬间换肤。一行搞定全 app 换主题。方案二Provider/Consumer组件树内如果不想用全局AppStorage用前面讲的状态共享完整示例EntryComponentV2struct Root{Provider(theme)theme:ThemeLightbuild(){/* 子树 */}}ComponentV2struct Child{Consumer(theme)theme:ThemeLightbuild(){Text(x).fontColor(this.theme.text)}}祖先Provider任意后代Consumer直接用切换theme全树更新。结合系统深色模式还可以读系统是否深色自动跟随代码解析import{configuration}fromkit.AbilityKitconstisDarkconfiguration.getConfiguration(getContext()).colorMode0AppStorage.set(theme,isDark?Dark:Light)常见误区小白必踩误区说明颜色写死字面值fontColor(#333)到处写切深色模式要改几百处。必须引用主题变量。不订阅StorageProp组件里直接读一次AppStorage主题变了它不重绘。用StorageProp订阅才自动更新。切换不更新只改了存的值但组件没订阅当然不变。订阅机制是关键。下面这段代码可以直接复制到 DevEco Studio 里运行。建议你边读边敲改一改文末「动手改一改」里的参数亲眼看看效果。完整可运行示例深色模式换肤监听系统深浅色或手动切换主题。实现拆解// 深色模式跟随系统 手动覆盖import{Configuration}fromkit.ArkUIEntryComponentstruct ThemeDemo{Statedark:booleanfalseaboutToAppear(){constcfggetContext().configthis.darkcfg.colorModeConfiguration.ColorMode.COLOR_MODE_DARK}build(){Column({space:16}){Text(当前(this.dark?深色:浅色)).fontSize(20)Button(切换).onClick((){this.dark!this.dark})}.width(100%).height(100%).backgroundColor(this.dark?#1A1A1A:#FFFFFF).padding(20)}}你会看到什么界面背景随dark在黑/白间切换。真实项目里应把颜色抽成Resource资源配合系统colorMode自动适配。动手改一改把背景色换成this.dark ? $r(app.color.bg_dark) : $r(app.color.bg_light)用资源文件管理。监听onConfigurationUpdate实现「系统切深色App 自动跟」。用一个Provide theme让全 App 共享主题状态。写在最后主题切换的本质是**“颜色变量化 集中管理”**。用AppStorage或Provider存一个主题对象组件全读它切换时改一处即可全 app 生效。千万别再写死颜色了。从今天起新建组件第一件事把颜色换成theme.xxx。等哪天产品说加个护眼绿主题你十分钟就搞定。
