1、场景描述
在实际的应用开发中,我们可能需要在界面中局部应用深色或者浅色的界面样式,与全局的深色、亮色同时生效。场景例如:深/亮色预览。此时,我们可以使用WithTheme能力来达到我们的效果。
2、WithTheme
WithTheme组件可以用于设置应用局部页面自定义主题风格,可设置子组件深浅色模式和自定义主题配色。其中自定义主题配色我们在之前的文章中已经有过讲解,详见:鸿蒙UI开发——自定义主题色。
WidthTheme接口定义如下:
WithTheme(options: WithThemeOptions)
其中WithThemeOptions定义如下:
struct WidthThemeOptions {/*用于自定义WithTheme作用域内组件缺省配色。默认值:undefined,缺省样式跟随系统token默认样式。*/theme: CustomTheme;/*用于指定WithTheme作用域内组件配色深浅色模式。默认值:ThemeColorMode.System。*/colorMode: ThemeColorMode;}
其中theme我们在之前自定义主题色的文章中已经有介绍,不再赘述,详见鸿蒙UI开发——自定义主题色。其中colorMode是深浅色的配置,其值是一个枚举,定义如下:
SYSTEM // 跟随系统深浅色模式。LIGHT // 固定使用浅色模式。DARK // 固定使用深色模式。
| 需要注意: WidthTheme不支持通用属性(例如:长/宽/背景色等)与通用事件(例如:点击、触摸、拖拽等)的设置。 |
3、使用示例
在WithTheme的作用范围内,组件的样式资源值会根据指定的模式,读取对应的深浅色模式系统和应用资源值。这意味着,在WithTheme作用范围内,组件的配色会根据所指定的深浅模式进行调整。
通过WithTheme({ colorMode: ThemeColorMode.DARK }),可以将作用范围内的组件设置为深色模式。
设置局部深浅色时,需要添加dark.json资源文件,深浅色模式才会生效。添加位置为:resources -> dark -> element -> dark.json(如果没有对应的文件或者文件夹,自己手动创建即可),示意图如下:

dark.json具体的示例代码如下:
{"color": [{"name": "start_window_background","value": "#FFFFFF"}]}
使用WidthTheme的示例如下(我们可以在Page中局部生效深色和亮色模式,代码见 18行、33行):
// 指定局部深浅色模式@Entry@Componentstruct Index {build() {Column() {// 系统默认Column() {Text('无WithTheme').fontSize(40).fontWeight(FontWeight.Bold)}.justifyContent(FlexAlign.Center).width('100%').height('33%').backgroundColor($r('sys.color.background_primary'))// 设置组件为深色模式WithTheme({ colorMode: ThemeColorMode.DARK }) {Column() {Text('WithTheme').fontSize(40).fontWeight(FontWeight.Bold)Text('DARK').fontSize(40).fontWeight(FontWeight.Bold)}.justifyContent(FlexAlign.Center).width('100%').height('33%').backgroundColor($r('sys.color.background_primary'))}// 设置组件为浅色模式WithTheme({ colorMode: ThemeColorMode.LIGHT }) {Column() {Text('WithTheme').fontSize(40).fontWeight(FontWeight.Bold)Text('LIGHT').fontSize(40).fontWeight(FontWeight.Bold)}.justifyContent(FlexAlign.Center).width('100%').height('33%').backgroundColor($r('sys.color.background_primary'))}}.height('100%').expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.END, SafeAreaEdge.BOTTOM, SafeAreaEdge.START])}}
效果如下(在同一个Page中,我们默认的样式为亮色,中间局部实现了深色模式渲染):

