Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >HarmonyOS 开发实践——基于原生能力的深色模式适配

HarmonyOS 开发实践——基于原生能力的深色模式适配

原创
作者头像
小帅聊鸿蒙
发布于 2024-11-11 12:43:19
发布于 2024-11-11 12:43:19
3350
举报
文章被收录于专栏:鸿蒙开发笔记鸿蒙开发笔记

场景描述

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

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

方案描述

场景一:跟随系统

效果

普通暗夜模式

方案

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

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

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

  1. 采用资源限定词目录的方式,自定义两套资源(resources/dark/media和resources/base/media),通过$r的方式加载颜色资源的key值。
  2. 对于 SVG 格式的一些简单图标,可以使用 fillColor 属性配合系统资源改变图片的绘制颜色。不通过两套图片资源的方式,也可以实现深浅色模式适配(补充:通过两套图片资源的方式也可以实现,修改svg图片中fill属性的颜色,然后将两张图片分别放置在不同的目录下)

3.页面状态栏的适配:

此处的代码要用到窗口的属性来设置状态栏图标的颜色,写在entry下(参考此章核心代码1);值得一提的是,barContentColor并不支持使用$r的方式加载颜色资源的key值,它是一个string类型的,因此,这里的是不是暗夜模式就要开发者自己去写代码判断。

4.基于Web组件适配:

支持对前端页面进行深色模式设置,通过darkMode 接口可以配置跟随系统。若网页未定义深色样式,则需开启强制深色模式 forceDarkAccess 使用。需要注意的要让网页跟随系统,请设置WebDarkMode为Auto。

核心代码:

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

  1. resources/base/element/color.json
代码语言:ts
AI代码解释
复制
{
      "name": "list_background",
      "value": "#FFFFFF"
    },

2. resources/dark/element/color.json

代码语言:ts
AI代码解释
复制
{
      "name": "list_background",
      "value": "#212224"
    },

3. 通过$r的方式加载颜色资源的key值。

代码语言:ts
AI代码解释
复制
 .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值
代码语言:ts
AI代码解释
复制
Image($r("app.media.loading"))

2.svg图片

代码语言:ts
AI代码解释
复制
resources/base/color

{       
  "name": "ic_public_back_color",       
  "value": "#212121"     
}

esources/dark/color

代码语言:ts
AI代码解释
复制
{       
  "name": "ic_public_back_color",       
  "value": "#dcdcdc"     
}
  • 通过$r的方式加载颜色资源的key值,通过fillcolor修改svg颜色
代码语言:ts
AI代码解释
复制
Image($r('app.media.ic_public_back'))
          .fillColor($r('app.color.ic_public_back_color'))

3.页面状态栏的适配:

代码语言:ts
AI代码解释
复制
 @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组件适配:(注意开启了强制网页适配,原因是指定网页没有定义深色样式)

代码语言:ts
AI代码解释
复制
 @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
      };
    })
  }

场景二:不跟随系统

效果

  1. setColorMode

方案

  • 通过setColorMode设置应用的颜色模式需要注意通过setColorMode改变模式,同样可以被this.context.config.colorMode以及onConfigurationOnUpdate监听
  • Web组件通过darkMode和forceDarkAccess属性,配置是否强制接入深色模式。

案例代码

  1. 通过setColorMode设置应用的颜色模式
代码语言:ts
AI代码解释
复制
@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即可

代码语言:ts
AI代码解释
复制
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)
    }
  }
}

写在最后

如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力;
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识;
  • 想要获取更多完整鸿蒙最新学习知识点,可关注B站:码牛课堂鸿蒙开发;

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
鸿蒙开发:适配系统深浅色模式
无论是Android还是iOS,在系统设置中,都有着深色和浅色两种外观模式,同样,鸿蒙系统中也存在这样的外观切换,如何让自己的应用,跟随着系统的模式进行动态切换呢?目前系统给我们提供了两种方式可以实现,一种是资源形式,一种是动态的代码形式。
程序员一鸣
2024/12/29
3460
鸿蒙开发:适配系统深浅色模式
纯血鸿蒙APP实战开发——深色模式适配
本示例介绍在开发应用以适应深色模式时,对于深色和浅色模式的适配方案,采取了多种策略如下:
小帅聊鸿蒙
2024/12/30
3220
Android实战:APP换肤功能,并自动适配手机深色模式
image.png Android换肤功能已不是什么新鲜事了,市面上有很多第三方的换肤库和实现方案。 之所以选择腾讯的QMUI库来演示APP的换肤功能,主要原因: 1、换肤功能的实现过程较简单、容易理解; 2、能轻松适配Android 10 提供的Dark Mode(深色模式) ; 3、还能白嫖QMUI的各种组件、效果(这才是重要的,😁哈哈~); 1、换肤流程实现: 1.1、新建工程 通过AndroidStudio新建一个空工程(新建工程的过程,略),并添加QMUI依赖: implementation
玖柒的小窝
2021/12/06
1.3K0
Android实战:APP换肤功能,并自动适配手机深色模式
深色模式适配指南
随着 iOS 13 的发布,深色模式(Dark Mode)越来越多地出现在大众的视野中,支持深色模式已经成为现代移动应用和网站的一个潮流,前段时间更是因为微信的适配再度引起热议。深色模式不仅可以大幅减少电量的消耗,减弱强光对比,还能提供更好的可视性和沉浸感。
政采云前端团队
2020/08/18
3K0
深色模式适配指南
DarkMode(2):深色模式解决方案——css颜色变量实现Dark Mode
暗黑模式实现,最初的设计,就是参考之前的主题模式。所谓多套主题/配色/皮肤,就是我们很常见的换肤功能。换肤简单的实现就是更换 css实现不同样式呈现不同肤色。
周陆军
2020/12/11
3.7K0
HarmonyOS访问资源
在应用开发的hml和js文件中使用$r的用法,可以对JS模块内的resources目录下的json资源进行格式化,获取相应的资源内容。
酒楼
2023/11/25
3990
五一了 谈一谈最近的近况 孵化两个上线项目
话题不知道从哪里开始说起,尤其佩服很多出口成章的同学可以写出各种既能表达自己想法,又能用这种修辞美好言语的同学。像我是很典型的理工男思维,连给女儿讲一讲白雪公主的故事都是这样
万少
2025/05/03
1080
五一了 谈一谈最近的近况 孵化两个上线项目
HarmonyOS学习路之开发基础知识——资源文件
应用的资源文件(字符串、图片、音频等)统一存放于resources目录下,便于开发者使用和维护。resources目录包括两大类目录,一类为base目录与限定词目录,另一类为rawfile目录 资源目录示例:
爱吃土豆丝的打工人
2021/11/10
9270
HarmonyOS学习路之开发基础知识——资源文件
HarmonyOS 开发实践——基于原生能力的跨应用跳转
使用原生能力startability启动其他应用前,开发者需要判断目标应用是否安装,从而执行不同的逻辑,例如:
小帅聊鸿蒙
2024/11/08
3110
HarmonyOS 开发实践——基于原生能力的跨应用跳转
DarkMode(5):深色模式不同实现方案切换
在《DarkMode(2):深色模式解决方案——css颜色变量实现Dark Mode》与《DarkMode(3):深色模式解决方案——颜色反转与函数 》,如果使用
周陆军
2020/12/11
9900
HarmonyOS APP应用主题切换
本示例展示多种应用主题切换。通过创建 base 同级资源文件夹 dark 和 light 完成深色浅色主题相关资源配置,实现深色浅色主题切换,在 ThemeConst 文件中配置自定义主题文件,通过控制变量实现多主题切换。
小帅聊鸿蒙
2024/09/12
2940
HarmonyOS APP应用主题切换
Electron入门教程4 —— 切换应用的主题
如果您想要手动在亮/暗模式之间切换,您可以通过在nativeTheme模块的themeSource属性中设置所需的模式来做到这一点。此属性的值将传播到您的渲染进程。任何与prefers-color-scheme相关的CSS规则都将相应地更新。
害恶细君
2022/11/22
1.1K0
Electron入门教程4 —— 切换应用的主题
HarmonyOS 开发实践 —— 基于原生能力的各类通知管理
除了基础类型通知外还包含长文本类型和多行文本类型,长文本和多行文本类型通知支持展开,通知对比如下:
小帅聊鸿蒙
2024/12/18
2390
HarmonyOS 开发实践 —— 基于原生能力的各类通知管理
81.[HarmonyOS NEXT 实战案例十五] 电商分类导航网格布局(进阶篇)
在上一篇教程中,我们学习了如何使用HarmonyOS NEXT的GridRow和GridCol组件实现基础的电商分类导航网格布局。本篇教程将在此基础上,深入探讨如何优化和扩展电商分类导航,实现更加灵活、美观和功能丰富的界面。
全栈若城
2025/06/08
1090
手把手带你撸一个网易云音乐首页-适配篇
Hello, 大家好,今天是和大家分享如何用 Swift 开发网易云音乐首页的第四篇文章,在前几篇文章中我分别和大家分享了如何使用 MVVM 模式来构建应用,以下是文章的直通车:
HelloWorld杰少
2022/08/04
6100
手把手带你撸一个网易云音乐首页-适配篇
Nuxt3在使用Tailwindcss情况下,如何优雅实现深色模式切换?
随着前端更新,网站设计中,深色模式也成为了一种备受欢迎的设计趋势。可以帮助用户减少眼睛的负担,同时也更加适合在光线较暗的环境下使用。
Mintimate
2023/07/31
2.4K0
Nuxt3在使用Tailwindcss情况下,如何优雅实现深色模式切换?
快速适配 Flutter 之深色模式
深色模式(Dark Mode),也被称为暗黑模式,是一种高对比度,或者反色模式的显示模式,开启之后在夜间可以缓解疲劳,更易于阅读,同时也能在一定程度上达到省电的效果。iOS和安卓分别从 iOS 13 和 Android 10(不同厂商不尽相同,部分 Android 9 也支持) 开始加入深色模式的支持,各大浏览器纷纷开始支持深色模式,强如微信也终于在 iOS 客户端 7.0.12、Android 客户端 7.0.13 支持了深色模式,等网页端适配深色模式后将更进一步提高用户体验的一致性。
出其东门
2020/05/13
2K0
鸿蒙原生开发手记:01-元服务开发
元服务是鸿蒙中的一种轻量应用形态,无需下载,直接运行。类似于微信小程序,但与小程序不同的是,元服务更加轻量。
少湖说
2024/11/14
2050
鸿蒙原生开发手记:01-元服务开发
132.[HarmonyOS NEXT 实战案例五:SideBarContainer] 侧边栏容器实战:悬浮模式侧边栏(Overlay)进阶篇
在基础篇中,我们已经实现了移动端抽屉菜单的基本布局和功能。在本篇教程中,我们将深入探讨如何通过状态管理和交互功能增强,使侧边栏更加智能和易用。
全栈若城
2025/06/30
1730
Android 深色模式的项目应用
早在四年前就准备做深色模式的,当时用的三方的SDK,但是SDK上还有bug,不能适配RecyclerView,用上后会很卡,然后就一直放着了,有些用户一直催着要深色模式:
Jingbin
2021/11/29
1.5K5
Android 深色模式的项目应用
推荐阅读
相关推荐
鸿蒙开发:适配系统深浅色模式
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档