场景描述
对于原生开发的应用,深色模式适配是开发过程中常见的业务场景,系统可以通过状态栏中的深色模式开关配置系统的颜色模式,当系统颜色模式方式变化时,应用经常会遇到如下的业务诉求:
场景一:跟随系统变化,感知系统颜色模式发生变化,无需重启应用,完成资源切换。
场景二:不跟随系统变化,应用固定使用某种颜色模式,不跟随系统颜色模式变化。
方案描述
场景一:跟随系统
效果
普通暗夜模式
方案
1.基于资源文件的组件颜色适配:
自定义两套颜色资源(resources/dark/element/color.json和resources/base/element/color.json),通过$r的方式加载颜色资源的key值。通过系统资源实现,开发者可直接使用的系统预置资源,即分层参数,同一资源ID在设备类型、深浅色等不同配置下有不同的取值。通过使用系统资源,不同的开发者可以开发出具有相同视觉风格的应用,不需要自定义2份颜色资源,在深浅色模式下也会自动切换成不同的颜色值。
2.基于媒体文件的图片资源适配:
HarmonyOS图标库链接: https://developer.huawei.com/consumer/cn/design/harmonyos-icon/
采用资源限定词目录的方式,自定义两套资源(resources/dark/media和resources/base/media),通过$r的方式加载颜色资源的key值。
对于 SVG 格式的一些简单图标,可以使用 fillColor 属性配合系统资源改变图片的绘制颜色。不通过两套图片资源的方式,也可以实现深浅色模式适配(补充:通过两套图片资源的方式也可以实现,修改svg图片中fill属性的颜色,然后将两张图片分别放置在不同的目录下)
3.页面状态栏的适配:
此处的代码要用到窗口的属性来设置状态栏图标的颜色,写在entry下(参考此章核心代码1);值得一提的是,barContentColor并不支持使用$r的方式加载颜色资源的key值,它是一个string类型的,因此,这里的是不是暗夜模式就要开发者自己去写代码判断。
4.基于Web组件适配:
支持对前端页面进行深色模式设置,通过darkMode 接口可以配置跟随系统。若网页未定义深色样式,则需开启强制深色模式forceDarkAccess使用。需要注意的要让网页跟随系统,请设置WebDarkMode为Auto。
核心代码:
1.基于资源文件的组件颜色适配:
- resources/base/element/color.json
{ "name": "list_background", "value": "#FFFFFF" },
- resources/dark/element/color.json
{ "name": "list_background", "value": "#212224" },
- 通过$r的方式加载颜色资源的key值。
.backgroundColor($r('app.color.list_background'))
2.基于媒体文件的图片资源适配:
1.普通png图片
- resources/base/media
路径resources/base/media/loading.png
- resources/dark/media
路径resources/dark/media/loading.png
- 通过$r的方式加载颜色资源的key值
Image($r("app.media.loading"))
2.svg图片
resources/base/color
{
"name": "ic_public_back_color",
"value": "#212121"
}
esources/dark/color
{
"name": "ic_public_back_color",
"value": "#dcdcdc"
}
- 通过$r的方式加载颜色资源的key值,通过fillcolor修改svg颜色
Image($r('app.media.ic_public_back'))
.fillColor($r('app.color.ic_public_back_color'))
3.页面状态栏的适配:
@State isDarkMode: boolean = false
@State barContentColor: string = ''
private context = getContext(this) as common.UIAbilityContext
// 状态栏适配黑夜模式
onPageShow(): void {
window.getLastWindow(getContext(this), (err, win) => {
//判断是否是暗夜模式(因为有三种)
if(this.context.config.colorMode==1){
this.isDarkMode = false
}
if(this.context.config.colorMode==0){
this.isDarkMode = true
}
//因为barContentColor只能取string类型的值,所以不能直接用resource资源来适配
this.barContentColor = this.isDarkMode ? '#ffffff' : '#000000'
let SystemBarProperties: window.SystemBarProperties = {
statusBarContentColor: this.barContentColor
};
})
}
4.基于Web组件适配:(注意开启了强制网页适配,原因是指定网页没有定义深色样式)
// xxx.ets
import web_webview from '@ohos.web.webview'
@Entry
@Component
struct WebComponent {
controller: web_webview.WebviewController = new web_webview.WebviewController()
@State mode: WebDarkMode = WebDarkMode.Auto
@State access: boolean = true
build() {
Column() {
Web({ src: 'www.xxx.com', controller: this.controller })
.darkMode(this.mode)
.forceDarkAccess(this.access)
}
}
}
场景二:不跟随系统
效果
- setColorMode
方案
- 通过setColorMode设置应用的颜色模式需要注意通过setColorMode改变模式,同样可以被this.context.config.colorMode以及onConfigurationOnUpdate监听
- Web组件通过darkMode和forceDarkAccess属性,配置是否强制接入深色模式。
案例代码
1.通过setColorMode设置应用的颜色模式
@Entry
@Component
struct TogglePage2 {
@State isDarkMode: boolean = false
build() {
Column() {
Toggle({ type: ToggleType.Switch ,isOn:this.isDarkMode})//isOn 属性值在有触发刷新页面的场景中,不要省略
.onChange((isOn: boolean) => {
console.log('Toggle.onChange2: isOn', isOn)
this.isDarkMode = isOn
getContext(this).getApplicationContext().setColorMode(this.isDarkMode?0:1) //触发二次渲染,渲染不给isOn 熟悉赋值会给默认值false,导致状态不对
})
}.width("100%").height("100%").padding(32)
}
}
2.Web组件通过[darkMode]和[forceDarkAccess]属性,配置是否强制接入深色模式案例代码,设置darkMode为On即可
import web_webview from '@ohos.web.webview'
@Entry
@Component
struct WebComponent {
controller: web_webview.WebviewController = new web_webview.WebviewController()
@State mode: WebDarkMode = WebDarkMode.On
@State access: boolean = true
build() {
Column() {
Web({ src: 'www.xxx.com', controller: this.controller }).darkMode(this.mode).forceDarkAccess(this.access)
}
}
}
最后
小编在之前的鸿蒙系统扫盲中,有很多朋友给我留言,不同的角度的问了一些问题,我明显感觉到一点,那就是许多人参与鸿蒙开发,但是又不知道从哪里下手,因为资料太多,太杂,教授的人也多,无从选择。有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)文档用来跟着学习是非常有必要的。
为了确保高效学习,建议规划清晰的学习路线,涵盖以下关键阶段:
→【纯血版鸿蒙全套最新学习文档】希望这一份鸿蒙学习文档能够给大家带来帮助~
鸿蒙(HarmonyOS NEXT)最新学习路线
该路线图包含基础技能、就业必备技能、多媒体技术、六大电商APP、进阶高级技能、实战就业级设备开发,不仅补充了华为官网未涉及的解决方案
路线图适合人群:
IT开发人员:想要拓展职业边界
零基础小白:鸿蒙爱好者,希望从0到1学习,增加一项技能。
技术提升/进阶跳槽:发展瓶颈期,提升职场竞争力,快速掌握鸿蒙技术
2.学习视频+学习PDF文档
HarmonyOS Next 最新全套视频教程 (鸿蒙语法ArkTS、TypeScript、ArkUI教程……)
纯血版鸿蒙全套学习文档(面试、文档、全套视频等)
鸿蒙APP开发必备
总结
总的来说,华为鸿蒙不再兼容安卓,对程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,才能在这个变革的时代中立于不败之地。