鸿蒙5.0实战案例:基于原生能力的深色模式适配

往期推文全新看点(文中附带全新鸿蒙5.0全栈学习笔录)

✏️ 鸿蒙(HarmonyOS)北向开发知识点记录~

✏️ 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~

✏️ 鸿蒙应用开发与鸿蒙系统开发哪个更有前景?

✏️ 嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~

✏️ 对于大前端开发来说,转鸿蒙开发究竟是福还是祸?

✏️ 鸿蒙岗位需求突增!移动端、PC端、IoT到底该怎么选?

✏️ 记录一场鸿蒙开发岗位面试经历~

✏️ 持续更新中......


场景描述

对于原生开发的应用,深色模式适配是开发过程中常见的业务场景,系统可以通过状态栏中的深色模式开关配置系统的颜色模式,当系统颜色模式方式变化时,应用经常会遇到如下的业务诉求:

场景一:跟随系统变化,感知系统颜色模式发生变化,无需重启应用,完成资源切换。

场景二:不跟随系统变化,应用固定使用某种颜色模式,不跟随系统颜色模式变化。

方案描述

场景一:跟随系统

效果

普通暗夜模式

方案

1.基于资源文件的组件颜色适配:

自定义两套颜色资源(resources/dark/element/color.json和resources/base/element/color.json),通过$r的方式加载颜色资源的key值。通过系统资源实现,开发者可直接使用的系统预置资源,即分层参数,同一资源ID在设备类型、深浅色等不同配置下有不同的取值。通过使用系统资源,不同的开发者可以开发出具有相同视觉风格的应用,不需要自定义2份颜色资源,在深浅色模式下也会自动切换成不同的颜色值。

2.基于媒体文件的图片资源适配:

采用资源限定词目录的方式,自定义两套资源(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.基于资源文件的组件颜色适配:

  1. resources/base/element/color.json

    复制代码
    {
          "name": "list_background",
          "value": "#FFFFFF"
        },
  2. resources/dark/element/color.json

    复制代码
    {
          "name": "list_background",
          "value": "#212224"
        },
  3. 通过$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)
    }
  }
}

场景二:不跟随系统

效果

  1. 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)
    }
  }
}
相关推荐
zhanshuo7 小时前
在鸿蒙里优雅地处理网络错误:从 Demo 到实战案例
harmonyos
公众号【林东笔记】获取资料7 小时前
Adobe Photoshop 2024:软件安装包分享和详细安装教程
ui·adobe·photoshop
zhanshuo7 小时前
在鸿蒙中实现深色/浅色模式切换:从原理到可运行 Demo
harmonyos
whysqwhw13 小时前
鸿蒙分布式投屏
harmonyos
whysqwhw14 小时前
鸿蒙AVSession Kit
harmonyos
whysqwhw16 小时前
鸿蒙各种生命周期
harmonyos
whysqwhw17 小时前
鸿蒙音频编码
harmonyos
whysqwhw17 小时前
鸿蒙音频解码
harmonyos
whysqwhw17 小时前
鸿蒙视频解码
harmonyos
whysqwhw17 小时前
鸿蒙视频编码
harmonyos