HarmonyOS NEXT应用开发之深色模式适配
介绍
本示例介绍在开发应用以适应深色模式时,对于深色和浅色模式的适配方案,采取了多种策略如下:
- 固定属性适配:对于部分组件的颜色属性,如背景色或字体颜色,若保持不变,可直接设定固定色值或引用固定的资源文件。
- 双资源目录适配:在resources目录下新增dark子目录,用于存放深色模式下的特定颜色配置(color.json文件)和图片资源(media文件)。在深色模式下,系统会自动加载此目录中的颜色及图片资源,确保与浅色模式下的UI元素色彩差异性。
- 利用系统分层参数:对于支持深浅模式切换的系统层级颜色资源,我们可以直接引用这些具有分层特性的参数,使得当切换设备主题时,相关组件的颜色能根据系统当前颜色模式自动更新。
- 监听当前颜色模式变化:通过注册AbilityStage.onConfigurationUpdate事件监听器,实时捕捉到设备深浅颜色模式的变化,并据此动态调整UI布局结构或逻辑处理,以适应不同模式下的最佳视觉体验。
效果图预览

使用说明
- 在应用主页点击“深色模式”案例,将应用切至后台,系统颜色模式发生改变(如在系统设置中切换深浅色模式),当应用重新被激活至前台时,能够立即检测到系统颜色模式的变化,并自动更新为对应颜色主题的视图界面。
实现思路
- 当UI组件的颜色属性被设置为固定颜色值时,其在深色模式和浅色模式下的显示颜色将保持不变。
// 将Text直接设置成'#000000'固定色值
Text("精品好礼")
.opacity(0.6)
.fontColor($r('app.color.black_font_color'))
.margin({ left: $r('app.integer.text_margin_left') })
- 为了实现深色模式下的颜色适配,可以在resources目录下新建'dark/element'的子目录,并在此目录中创建color.json文件。为深色模式下的各个UI组件指定相应的颜色值,务必确保与浅色模式下同名颜色资源名称一致,以确保系统能够正确识别并切换。
// 用资源ID方式设置Column背景色。(浅色模式色值为'#FA5A3C'、深色模式色值为'#000000')
.backgroundColor($r('app.color.column_bg_color'))
- 若UI组件的颜色属性引用的是系统提供的具有层级参数的颜色资源,则当设备在深色模式和浅色模式间切换时,这些颜色会自动调整至对应模式下的预设色值。
// 用系统提供的分层参数颜色资源方式设置色值
Text(item.price)
.fontSize($r('app.integer.goods_font'))
.offset({ x: -3 })// 因为¥是中文字符,上面的是中文字符,占的宽度不一样,所以需要对齐,添加offset
.fontColor($r('sys.color.ohos_id_color_foreground'))
- 对于PNG、WEBP或JPEG格式的图片资源,若需支持深色模式,应在resources目录下新增一个'dark/media'子目录,将深色模式下对应的图片放入此目录,并确保图片文件名与浅色模式下的图片相同,以便系统根据当前模式加载合适的图片资源。
// SVG格式图片fillColor颜色资源ID方式设置(浅色模式色值为'#000000'、深色模式色值为'#FFFFFF')
Image($r('app.media.view'))
.fillColor($r('app.color.view_fill_color'))
.width($r('app.integer.view_image_width'))
.aspectRatio(1)
.objectFit(ImageFit.Contain)
- 在存在深浅两种模式下布局结构或逻辑处理有所差异的情况时,开发者应当利用AbilityStage.onConfigurationUpdate监听接口来实时感知系统主题的变化,并据此做出相应的布局调整或逻辑处理,从而确保应用能够在不同模式下呈现出理想的界面效果及功能体验。
- 第一步保存全局参数,并通过onConfigurationUpdate刷新状态栏
// 获取当前的颜色模式并保存并在onConfigurationUpdate
AppStorage.setOrCreate('currentColorMode', this.context.config.colorMode);
// 保存windowStage供fitfordarkmode的har包中FitForDarkPage.ets中setStatusBar方法修改状态栏颜色。
AppStorage.setOrCreate('windowStage', windowStage);
// 检测当前的深浅模式是否发生变化,刷新状态栏
onConfigurationUpdate(config: Configuration) {
// 获取最新的变更颜色并更新到AppStorage
AppStorage.setOrCreate('currentColorMode', config.colorMode);
logger.info(`onConfigurationUpdate, config: ${JSON.stringify(config)}`);
}
- 第二步在FitForDarKMode.ets中获取并监听当前颜色模式
// @StorageProp + @Watch 获取并监听当前颜色模式
@StorageProp('currentColorMode') @Watch('onColorModeChange') currentMode: number = 0;
// @Watch回调函数,监听颜色模式刷新状态变量
onColorModeChange(): void {
if (this.currentMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK) {
this.banner = $r("app.media.dark_mode_banner");
} else {
this.banner = $r("app.media.light_mode_banner");
}
}
- 第三步在FitForDarKMode.ets生命周期aboutToAppear中根据当前颜色模式刷新banner状态变量,切换不同的图片。
// 在自定义组件生命周期aboutToAppear中,根据当前颜色模式刷新banner状态变量,切换不同的图片。
aboutToAppear(): void {
if (this.currentMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK) {
this.banner = $r("app.media.dark_mode_banner");
} else {
this.banner = $r("app.media.light_mode_banner");
// 在当前为浅色模式中,确保界面美观且颜色统一,设置导航栏的背景色。
setStatusBar(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
}
}
- 第四步在FitForDarKMode.ets生命周期aboutToDisappear中,重置导航栏的背景色避免影响其它页面的导航栏为红色。
// 在自定义组件生命周期aboutToDisappear中,重置导航栏的背景色避免影响其它页面的导航栏为红色。
aboutToDisappear(): void {
setStatusBar(this.currentMode)
}
- 第五步在FitForDarKMode.ets生命周期aboutToDisappear中,重置导航栏的背景色避免影响其它页面的导航栏为红色。
// 调用setWindowSystemBarProperties()设置状态栏及导航栏的颜色
windowClass.setWindowSystemBarProperties(sysBarProps, (err) => {
if (err.code) {
logger.error('Failed to set the system bar properties. Cause: ' + JSON.stringify(err));
return;
}
logger.info('Succeeded in setting the system bar properties.');
});
高性能知识点
不涉及
工程结构&模块类型
fitfordarkmode // har类型
|---mock
| |---GoodsMock.ets // 商品列表数据
|---mode
| |---GoodsModel.ets // 商品数据类型定义
|---view
| |---FitForDarkMode.ets // 深色模式适配主页面
| |---GoodsList.ets // 商品列表自定义组件
模块依赖
本实例依赖common模块来实现资源的调用以及公共组件FunctionDescription的引用。 还需要依赖EntryAbility.ets模块。
参考资料
@ohos.app.ability.ConfigurationConstant (ConfigurationConstant)
HarmonyOS NEXT应用开发之深色模式适配的更多相关文章
- iOS 深色模式适配
要求:iOS13.0以上 重点:需要所有界面进行适配,工作量巨大,需要从项目开始就进行适配:H5界面无法进行适配 实现方式:System Colors(常用).Semantic Colors(常用). ...
- Android QMUI实战:实现APP换肤功能,并自动适配手机深色模式
Android换肤功能已不是什么新鲜事了,市面上有很多第三方的换肤库和实现方案. 之所以选择腾讯的QMUI库来演示APP的换肤功能,主要原因: 1.换肤功能的实现过程较简单.容易理解: 2.能轻松适配 ...
- Mac上深色模式下的精美炫酷软件
针对发布的 macOS Mojave 10.14 系统中,最大的改变就是引入了深色模式,尤其对技术开发人员来说非常实用,非常的酷! 深色模式使用一种较深的配色方案,这种配色作用于整个系统,包括 Mac ...
- web开发中移动端适配
这个话题有些复杂,说起来有些琐碎,因为和移动端适配相关的问题太多了. 1. 概念 1.1 设备像素 设备像素被称为物理像素,它是显示设备中一个最小的物理部件.每个像素可以根据操作系统设置自己的颜色和亮 ...
- HarmonyOS三方件开发指南(17)-BottomNavigationBar
目录: 1.引言 2.功能介绍 3.BottomNavigationBar使用指南 4.BottomNavigationBar开发指南 5.<HarmonyOS三方件开发指南>文章合集 引 ...
- 图像开发的p2s模式:halcon+opencv的联动
[<zw版·Halcon与delphi系列原创教程> 图像开发的p2s模式:halcon+opencv的联动 尽管halcon功能强大,基本上cv只是halcon的一个子集,不过cv毕竟是 ...
- App开发三种模式
APP开发三种模式 现在App开发的模式包含以下三种: Native App 原生开发AppWeb App 网页AppHybrid App 混合原生和Web技术开发的App 详细介绍: http:// ...
- .net之微信企业号开发(三) 回调模式的接口开发
一.前言 微信企业号应用中,有两种模式,一种是普通模式,这种模式只能进行简单网页链接,以及发送固定的消息.为了可以让企业号的用户更好的与应用交互,微信提供了回调模式,这种回调模式的可以将用户发送给微信 ...
- Python 制作Android开发 所需的适配不同分辨率的套图
使用Python做起工具来还真是爽,简单,方便,快捷.今天忙活了一下,制作出一个比较实用的小工具. 自动化套图制作,适配不同屏幕 尤其是对于android开发来说,要适配不同屏幕就需要多套切图,那么. ...
- 「技巧」如何将Sketch改为深色模式
之前Sketch只能根据mac系统的外观设置变更皮肤.在更新了版本54之后,可以脱离操作系统,在自己的偏好设置中更改外观了. 准备 Sketch 54 更多工具:whose.design 第一步:打开 ...
随机推荐
- C#事件(event)的理解
一.多播委托的应用--观察者模式 遇到一个开发的问题? 面试者:以面向对象的思想实现一下的场景: 猫:Miao一声,紧接着引发了一系列的行为~ Miao:引发了一系列的动作: 从代码层面来说:代码这样 ...
- day03-应用线程01
JavaGUI-坦克大战03 7.线程的应用01 7.1坦克子弹发射思路 在坦克大战2.0基础上添加如下功能:当玩家按下 j 键,就发射一颗子弹. 思路: 当发射一颗子弹后,就等于启动了一个线程 He ...
- AOSP中获取系统签名
制作系统签名: 1.将AOSP源码路径下build\target\product\security\platform.pk8和platform.x509.pem复制出来放在同一目录下 2.执行命令 后 ...
- Django_文件下载
一.小文件下载 1.视图 views.py 三种方式实现,任选其一 (1)使用HttpResponse # 导入模块from django.shortcuts import HttpResponse ...
- SSH和SFTP是否相同
SSH和SFTP是否相同?SSH和SFTP是经典的对.在确保通信安全方面,它们交织在一起,尽管它们具有类似的功能,但它们并不是一回事.那么,它们之间有什么区别?请仔细阅读,找出答案. 什么是SSH? ...
- KingbaseES 配置root.sh实现数据库服务开机自启动
案例说明: KingbaseES数据库在部署完成后,支持数据库服务开机自启动,部署完成后,root用户(Linux)执行安装软件目录下的root.sh脚本后,可以实现数据库服务开机自启动. 适用版本: ...
- 美团一面:项目中使用过Redis吗?我说用Redis做缓存。他对我哦了一声
引言 Redis,作为一种开源的.基于内存且支持持久化的键值存储系统,以其卓越的性能.丰富灵活的数据结构和高度可扩展性在全球范围内广受欢迎.Redis不仅提供了一种简单直观的方式来存储和检索数据,更因 ...
- rv1126 mpp部署加解决问题
rv1126 mpp部署 + test 执行失败问题 1.1 mpp 环境部署 首先在我们自己的sdk中 ~/rv1126_linux_240110/external/mpp 将改目录拷贝到需要的 ...
- 无监督学习-K-means算法
无监督学习-K-means算法 1. 什么是无监督学习 一家广告平台需要根据相似的人口学特征和购买习惯将美国人口分成不同的小组,以便广告客户可以通过有关联的广告接触到他们的目标客户. Airbnb 需 ...
- HashSet 存对象的时候是如何判断是不是同一个对象,其中含有重写equals方法和hashcode方法 后续
一开始,set集合里面只存进一个对象, 存第二个对象时候,由于重写了hashcode方法,只要价格都是10就返回1,所以hashcode一样的话,再去进行equals方法判断,此时这个也重写了,thi ...