HarmonyOS鸿蒙Next中如何给自己的应用适配深浅主题模式?

HarmonyOS鸿蒙Next中如何给自己的应用适配深浅主题模式? 需要跟随系统设置或者应用内自定义切换

5 回复

真机效果:

cke_16109.gif

1、通过setColorMode这个API来实现系统以及应用内的自定义切换; 2、在对应的资源目录dark【深色】同步配置base【浅色】目录下即可

  • 颜色: cke_2324.jpeg
  • 媒体资源【图片等】: cke_3568.jpeg cke_4243.jpeg
参数名 类型 必填 说明
colorMode ConfigurationConstant.ColorMode 设置颜色模式,包括:- COLOR_MODE_DARK:深色模式- COLOR_MODE_LIGHT:浅色模式- COLOR_MODE_NOT_SET:不设置(跟随系统或应用)

使用方式:

//浅色
this.getUIContext().getHostContext()?.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT);
//深色
this.getUIContext().getHostContext()?.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_DARK);
//跟随系统
this.getUIContext().getHostContext()?.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);

完整代码:

import { ConfigurationConstant } from "@kit.AbilityKit"

@Component
export struct ChangeTheme {
  build() {
    Column() {
      Text('文本变化').fontColor($r('app.color.ft_main')).padding(20).backgroundColor($r('app.color.bg_main'))
      Image($r('app.media.background')).width(88).margin({ top: 15 })
      Button('浅色主题').margin({ top: 15 })
        .onClick(() => {
          this.setTheme(ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT)
        })
      Button('深色主题').margin({ top: 15 })
        .onClick(() => {
          this.setTheme(ConfigurationConstant.ColorMode.COLOR_MODE_DARK)
        })
      Button('跟随系统').margin({ top: 15 })
        .onClick(() => {
          this.setTheme(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET)
        })
    }
  }

  setTheme(code: ConfigurationConstant.ColorMode) {
    this.getUIContext().getHostContext()?.getApplicationContext().setColorMode(code);
  }
}

//组件引用
@Entry
@Component
struct Index {
  build() {
    Column() {
      ChangeTheme()
    }.justifyContent(FlexAlign.Center)
    .height('100%')
    .width('100%')
  }
}

**注意:**本示例仅提供实现,需要持久化设置同步到本地请自行实现。

相关文档:【官网指南_深浅色适配】

更多关于HarmonyOS鸿蒙Next中如何给自己的应用适配深浅主题模式?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


深色模式适配

概述

深色模式(Dark Mode)又称为暗色模式,是与日常应用使用过程中的浅色模式(Light Mode)相对应的一种UI主题。深色模式最早来源于人机交互领域的研究和实践,该模式并非简单地将页面背景变为黑色,文字内容变为白色,而是提供一整套适配深色模式的应用配色主题。深色模式相较浅色模式更加柔和,能减少亮度对用户眼睛造成的刺激和疲劳,此外深色模式能在一定程度上降低应用功耗,提升续航表现。

应用深色模式适配,需遵循基本的UX设计原则,保障应用页面内容的易读性、舒适性和一致性,具体可参考深色模式设计原则。应用适配过程主要包含字体颜色、元素背景色等颜色资源的适配,媒体资源如图片图标的适配,以及系统状态栏的适配,此外需要对一些特殊情况如使用了Web组件加载的Web页面进行处理。

本文主要将介绍深色模式的适配过程,同时会列举出适配过程中的常见问题及解决方案。

实现原理

当系统切换到深色模式后,应用内可能会出现部分内容切换到深色主题的情况,例如状态栏、弹窗背景色、系统控件等,会导致应用内页面效果错乱。

为应对上述情况,需要对应用进行深色模式下的内容适配,目前该适配主要依靠资源目录。当系统对应的设置项发生变化后(如系统语言、深浅色模式等),应用会自动加载对应资源目录下的资源文件。

系统为深色模式预留了dark目录,该目录在应用创建时默认不存在,在进行深色模式适配时,需要开发者在src/main/resources中手动创建出dark目录,将深色模式所需的资源放置到该目录下。对于浅色模式所需的资源,可以放入默认存在的src/main/resources/base目录下。

说明

在进行资源定义时,需要在base目录与dark目录中定义同名的资源。例如在base/element/color.json文件中定义text_color为黑色,在dark/element/color.json文件中定义text_color为白色,那么当深浅色切换时,应用内使用了$(‘app.color.text_color’)作为颜色值的元素会自动切换到对应的颜色,而无需使用其他逻辑判断进行控制。

一般情况下深浅色模式切换不会导致应用界面产生结构上的变化,而是页面结构一致但是采用不同的主题配色、配图等,使得整个应用在切换到深色模式后依然保持自然美观,以下为深色模式适配的UX示例。

图1 深色模式适配UX示例图 深色模式适配UX示例图

从上图中可以看到,在应用进行深色模式适配过程中主要的适配项有颜色资源适配、媒体资源适配、状态栏适配,除此之外若应用内使用了Web组件加载的Web页面,那么还需对Web页面适配深色模式,具体适配方案可点击对应链接跳转到具体章节查看。

目前业内应用向用户提供的深浅色模式切换有以下两种常见方式。

  • 应用跟随系统深浅色模式切换 实现上,需要开发者使用setColorMode()方法将ColorMode设置为COLOR_MODE_NOT_SET(未设置颜色模式),然后应用在运行过程中就可以自动感知到系统颜色模式切换,若应用完成了深浅色模式适配,将自动切换到对应的颜色模式。
  • 应用内提供手动控制深浅色的开关供用户自行选择 实现上,切换深色模式需要调用setColorMode()方法将ColorMode设置为COLOR_MODE_DARK(深色模式),切换浅色模式需要将ColorMode设置为COLOR_MODE_LIGHT(浅色模式),这样就可以完成对应用深浅色的手动控制。

综上分析,深色模式适配内容如下表所示。

表1 深色模式适配内容

适配项 适配内容 适配方式
颜色资源适配 组件背景色,字体颜色等 1. 使用受支持的系统资源
2. 使用color.json资源文件
媒体资源适配 应用内使用到的图片、图标等 1. SVG类型图标可使用fillColor()属性
2. 使用media资源目录
状态栏适配 深浅模式下不同的状态栏表现,包括状态栏的背景色以及状态栏内时间等内容的字体颜色 1. 对应用背景色进行深浅色适配
2. 根据当前深浅色状态动态设置状态栏字体颜色
Web内容适配 应用内使用Web组件加载的Web页面 参考Web组件设置深色模式

详见开发文档:https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-dark-mode-adaptation

在HarmonyOS Next中适配深浅主题模式,需在resources目录下创建themes.json文件,定义lightdark主题的资源。在代码中使用ResourceManager获取当前主题,通过getTheme方法加载对应主题资源。界面元素使用$r('app.type.name')引用主题资源,系统会根据主题自动切换颜色值。

在HarmonyOS Next中为应用适配深浅主题模式,主要涉及资源定义和动态切换两个核心环节。

1. 定义主题资源

resources目录下的basedark等限定词子目录中,分别定义不同主题下的颜色、样式等资源。

例如,在resources/base/element/color.json中定义基础颜色:

{
  "color": [
    {
      "name": "background_color",
      "value": "#FFFFFF"
    }
  ]
}

resources/dark/element/color.json中定义深色模式颜色:

{
  "color": [
    {
      "name": "background_color",
      "value": "#000000"
    }
  ]
}

2. 在UI中引用资源

在ArkUI组件中直接引用定义好的资源名,系统会根据当前主题自动匹配:

@Entry
@Component
struct Index {
  build() {
    Column() {
      Text('Hello')
        .fontSize(30)
        .fontColor($r('app.color.text_color'))
    }
    .width('100%')
    .height('100%')
    .backgroundColor($r('app.color.background_color'))
  }
}

3. 跟随系统主题

应用默认会跟随系统主题设置。如需显式控制,可在module.json5中配置:

{
  "module": {
    "abilities": [
      {
        "name": "EntryAbility",
        "theme": "system" // 可选值:system, light, dark
      }
    ]
  }
}

4. 应用内动态切换主题

通过UIAbilityContextWindow对象可以动态获取和设置主题:

import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  // 获取当前系统主题
  private getSystemTheme(): string {
    const windowClass = window.getLastWindow(this.context);
    return windowClass.getWindowMode().colorMode;
  }

  // 设置应用主题
  private setAppTheme(theme: string) {
    const windowClass = window.getLastWindow(this.context);
    windowClass.setWindowBackgroundColor(theme);
  }
}

5. 监听系统主题变化

注册主题变化监听器,在系统主题改变时更新界面:

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

// 在UIAbility中监听
onWindowStageCreate(windowStage: window.WindowStage) {
  windowStage.on('themeChange', (newTheme) => {
    // 处理主题变更逻辑
    this.updateTheme(newTheme);
  });
}

关键点

  • 资源文件按主题分类存放,系统自动匹配
  • 使用资源引用($r)而非硬编码颜色值
  • 配置module.json5控制主题行为
  • 通过Window API实现动态切换
  • 监听主题变化事件保持界面同步

这种设计确保了应用能无缝适配系统主题,同时支持应用内自定义主题切换,提供一致的用户体验。

回到顶部