鸿蒙开发:web页面如何适配深色模式

前言

应用上架之前,如果你未考虑到深色模式,大概率会审核不通过,问题原因为:应用存在应用未适配深色模式显示问题,不符合鸿蒙应用UX设计规范。

当然了,如果你实在不想适配,也有一个取巧的办法,那就是暂不适配,统一设置为浅色模式。

TypeScript 复制代码
 // 设置应用为浅色模式
    let applicationContext = this.context.getApplicationContext()
    applicationContext.setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT)

以上的代码设置之后,应用就不会跟随系统模式切换而切换了,但是,取巧终归是取巧,也许现在官方没有严格要求,但是不代表日后不会,所以,为了日后应用的上架,还有深色模式下能给用户带来不一样的体验,建议还是该适配就适配。

对于原生的页面,适配非常的简单,这个在之前的文章中也有过概述,两种方式,一种是资源的方式,一种是代码的方式。

资源方式

对于资源方式,我们可以在resources中新建dark,创建和浅色对应的颜色和图片资源即可,如下图所示:

比如,可以在color.json中定义同名配色并赋予不同的色值。

浅色模式:base/element/color.json文件:

TypeScript 复制代码
{
  "color": [
    {
      "name": "app_title_color",
      "value": "#000000"
    }
  ]
}

深色模式:dark/element/color.json文件:

TypeScript 复制代码
{
  "color": [
    {
      "name": "app_title_color",
      "value": "#FFFFFF"
    }
  ]
}

当然了,图片也是类似的,这里就不一一举例了。

代码方式

代码方式就需要监听系统模式的切换了,根据不同的模式,手动设置相应的颜色,基本操作如下,当然了,并不是唯一的方式。

在UIAbility的onConfigurationUpdate进行监听模式改变,这里可以通过事件分发或者通过应用级变量的状态管理AppStorage保存当前colorMode值。

TypeScript 复制代码
import { Configuration, UIAbility } from '@kit.AbilityKit';


export default class EntryAbility extends UIAbility {


  onConfigurationUpdate(newConfig: Configuration): void {
    AppStorage.setOrCreate('colorMode', newConfig.colorMode);
  }
}

在其他的页面就可以通过@StorageLink装饰器监听colorMode字段的变化,根据不同的状态设置对应的资源即可。

TypeScript 复制代码
import { ConfigurationConstant } from '@kit.AbilityKit';


@StorageLink('colorMode') @Watch('colorModeChange') colorMode: ConfigurationConstant.ColorMode =
  ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET;


/**
 * 系统深色模式变化,可以重新设置主题
 */
colorModeChange() {
  if (this.colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK) {
    this.readerSetting.nightMode = true;
    this.readerSetting.fontColor = '#ffffff';
    this.readerSetting.themeColor = '#202224';
  } else {
    this.readerSetting.nightMode = false;
    this.readerSetting.fontColor = '#000000';
    this.readerSetting.themeColor = '#FFFFFF';
  }
  this.readerComponentController.setPageConfig(this.readerSetting);
}

以上的方式呢,都是原生的方式,很多的应用,除了原生渲染之外,还有着H5的渲染,针对H5页面,我们该如何动态切换深色和浅色模式呢?

方式一:加载不同模式的web页面

这种方式,说白了就是提供两个web页面,一个是浅色模式,一个是深色模式,我们检测到系统模式变化之后,动态的切换对应模式的页面即可,目前官方在某些功能里,也在使用这种方式,比如官方的一键登录功能,我们就可以发现,针对《认证协议》,就提供了一个浅色页面和一个深色页面。

基本代码如下:

TypeScript 复制代码
  controller?: WebviewController = new webview.WebviewController()

  import { ConfigurationConstant } from '@kit.AbilityKit';


@StorageLink('colorMode') @Watch('colorModeChange') colorMode: ConfigurationConstant.ColorMode =
  ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET;


/**
 * 系统深色模式变化,可以重新设置主题
 */
colorModeChange() {
  if (this.colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK) {
      this.controller?.loadUrl("深色页面")
  } else {
      this.controller?.loadUrl("浅色页面")
  }
  this.readerComponentController.setPageConfig(this.readerSetting);
}

方式二:CSS样式适配

方式一,由于是不同的页面,在模式切换的时候,web组件会重新加载,会有一定的延时,不会立马模式转换,并且,在有多个不同的web页面的情况下,会占用服务器资源,当然也会给web前端同学增加一定工作量。

如何实现在本来的页面中进行模式的立马切换?这里就要说到CSS样式了,它可以让web页面根据系统模式进行快速切换,做到0延时,这也是在开发中推荐的,当然了,web前端同学的工作量该做还得做,这是少不了的。

web前端设置

在网页开发过程中,web前端同学可以使用color-scheme和prefers-color-scheme属性进行深色模式适配。

首先,在head标签中添加如下信息,这里的color-scheme是一个CSS属性,用于表示网页支持的配色方案,可以影响表单、滚动条和CSS系统颜色。CSS系统颜色指Web组件内置的颜色,是部分元素未定义样式时应用的默认颜色。

TypeScript 复制代码
<meta name="color-scheme" content="light dark">

声明了meta之后,剩下的就是,深色和浅色的资源设置了,一般情况下我们只设置默认样式和深色样式即可,当然了你也可以使用浅色模式覆盖深色模式,样式的适配代码如下,只需要在不同模式下设置对应的资源即可。

TypeScript 复制代码
<style>
  /* 默认样式 */
  body { background-color: White; }
  /* 浅色样式,Web关闭深色模式时覆盖默认样式 */
  @media (prefers-color-scheme: light) {
    body { background-color: Gray; }
  }
  /* 深色样式,Web开启深色模式时覆盖默认样式 */
  @media (prefers-color-scheme: dark) {
    body { background-color: Black; }
  }
</style>

prefers-color-scheme是CSS中的一个媒体查询功能,可以检测系统的主题颜色。web前端同学可以通过该特性,为不同的系统主题颜色定义不同的网页CSS样式,以适应用户的主题偏好。

Web深色模式设置

web前端同学在设置好对应模式资源之后,我们需要给web组件的适配模式打开,方可生效,也就是通过darkMode()配置Web深色模式,因为默认状态下为关闭,我们可以设置为WebDarkMode.Auto,让它跟随系统模式进行动态切换。

还有一个注意事项时,那就是web组件的背景颜色,也需要根据模式动态的切换,否则就会出现,深色模式下先白后改变的状态,简单案例如下:

TypeScript 复制代码
import { webview } from '@kit.ArkWeb';
@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  @State isDark: boolean = false;
  build() {
    Column() {
      Web({ src: $rawfile('index.html'), controller: this.controller })
        .darkMode(WebDarkMode.Auto)
        .backgroundColor(this.isDark ? Color.Black : Color.White)
    }
  }
}

以上的代码设置之后,便可实现了web页面动态的模式切换。

相关总结

web前端页除了css设置之外,还可以通过js代码来监听模式的改变,进行动态的资源设置。

TypeScript 复制代码
 // 监听颜色方案变化事件
        window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
            let isDark = e.matches;//是否是深色模式
          
        });

对于深色模式,建议提前去做,因为到后面再想起来适配,需要全方位的资源替换,还要进行系统的测试验证,比较耗费时间和精力,所以,项目一开始,我们尽量把深色模式考虑进去。

相关推荐
爱笑的眼睛114 小时前
HarmonyOS心率传感器数据采集:从原理到高级应用实践
华为·harmonyos
消失的旧时光-19435 小时前
TCP 流通信中的 EOFException 与 JSON 半包问题解析
android·json·tcp·数据
JiaoJunfeng6 小时前
android 8以上桌面图标适配方案(圆形)
android·图标适配
参宿四南河三6 小时前
Android Compose快速入门手册(真的只是入门)
android·app
芦半山7 小时前
Looper究竟在等什么?
android
yuec7 小时前
iOS 26 你的 property 崩了吗?
ios·客户端
爱笑的眼睛117 小时前
HarmonyOS中Radio单选框组件的交互设计深度解析
华为·harmonyos
czhc11400756639 小时前
JAVA1027抽象类;抽象类继承
android·java·开发语言
jiangmiao20249 小时前
IOS开发 Runloop机制
ios·objective-c