HarmonyOS 鸿蒙Next中怎么设置深色模式

HarmonyOS 鸿蒙Next中怎么设置深色模式 需要设置三种状态,跟随系统、开启深色、关闭深色,应该怎么开发?

8 回复
  • 应用跟随系统深浅色模式切换:使用setColorMode()方法将ColorMode设置为COLOR_MODE_NOT_SET(未设置颜色模式),然后应用在运行过程中就可以自动感知到系统颜色模式切换,若应用完成了深浅色模式适配,将自动切换到对应的颜色模式。
  • 应用内提供手动控制深浅色的开关供用户自行选择:切换深色模式需要调用setColorMode()方法将ColorMode设置为COLOR_MODE_DARK(深色模式),切换浅色模式需要将ColorMode设置为COLOR_MODE_LIGHT(浅色模式),这样就可以完成对应用深浅色的手动控制。
const setColorMode = (context: common.UIAbilityContext, colorMode: ConfigurationConstant.ColorMode) => {
    try {
        context.getApplicationContext().setColorMode(colorMode);
    } catch (err) {
        let error = err as BusinessError;
        hilog.error(0x0000, 'ColorModeChangeFunctions',
        `setColorMode failed. error code=${error.code}, message=${error.message}`);
    }
}

const setAutoColorMode = (context: common.UIAbilityContext) => {
    setColorMode(context, ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
}

const setDarkColorMode = (context: common.UIAbilityContext) => {
    setColorMode(context, ConfigurationConstant.ColorMode.COLOR_MODE_DARK);
}

const setLightColorMode = (context: common.UIAbilityContext) => {
    setColorMode(context, ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT);
}

更多关于HarmonyOS 鸿蒙Next中怎么设置深色模式的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


一般这样做:

  1. 设置页做三个选项:跟随系统、深色、浅色。
  2. 用户选择后,把选中的主题模式持久化保存。
  3. 应用启动时读取保存值,再调用 applyTheme。
  4. 颜色和图片资源同时做好深浅色适配: resources/base/element/color.json resources/dark/element/color.json

可以参考下我写的这篇帖子,很简单的。

链接:https://developer.huawei.com/consumer/cn/forum/topic/0203201535922285152?fid=0109140870620153026

背景知识:

首先需要配置 dark 目录,填写好在深色模式的颜色、图片等,然后在代码中使用,context.setColorMode()

问题解决:

步骤一:创建爱你深色目录

cke_12083.png

步骤二:

context: common.UIAbilityContext =
        this.getUIContext().getHostContext() as common.UIAbilityContext;

if(this.enable){
    this.context.setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_DARK)
}else{
    this.context.setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT)
}

真机演示:

cke_19890.gif

第一步:建好深浅色资源

entry/src/main/resources/

base/element/color.json # 浅色

dark/element/color.json # 深色(这都自己建)

大概这样配就行

{
  "color": [
    { "name": "bg_page", "value": "#ffffff" },
    { "name": "text_main", "value": "#000000" }
  ]
}

第二步:要做全局状态管理

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

// 三态枚举
export enum ThemeMode {
  SYSTEM = 0,   // 跟随系统
  DARK = 1,     // 深色
  LIGHT = 2     // 浅色
}

export class ThemeManager {
  static prefs: preferences.Preferences | null = null;
  static currentMode: ThemeMode = ThemeMode.SYSTEM;

  // 初始化(APP启动时调用一次)
  static async init() {
    ThemeManager.prefs = await preferences.getPreferences(getContext(), 'theme_prefs');
    const val = ThemeManager.prefs.getInt('theme_mode', ThemeMode.SYSTEM);
    ThemeManager.currentMode = val as ThemeMode;
    ThemeManager.apply();
  }

  // 切换模式
  static setMode(mode: ThemeMode) {
    ThemeManager.currentMode = mode;
    ThemeManager.prefs?.putInt('theme_mode', mode);
    ThemeManager.prefs?.flush();
    ThemeManager.apply();
  }

  // 把当前模式设置到全局Context
  static apply() {
    const ctx = getContext();
    switch (ThemeManager.currentMode) {
      case ThemeMode.SYSTEM:
        ctx.setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
        break;
      case ThemeMode.DARK:
        ctx.setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_DARK);
        break;
      case ThemeMode.LIGHT:
        ctx.setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT);
        break;
    }
  }
}

第三步:设置

然后就是根据用户选择或者初始化的时候进行设置了

import { ThemeManager, ThemeMode } from '../common/ThemeManager';

@Entry
@Component
struct ThemeSettingPage {
  @State selected: ThemeMode = ThemeManager.currentMode;

  build() {
    Column() {
      Text('深色模式')
        .fontSize(20)
        .margin({ bottom: 20 })

      // 跟随系统
      Radio({ value: ThemeMode.SYSTEM, group: 'theme' })
        .checked(this.selected === ThemeMode.SYSTEM)
        .onChange(() => {
          this.selected = ThemeMode.SYSTEM;
          ThemeManager.setMode(ThemeMode.SYSTEM);
        })
      Text('跟随系统')

      // 开启深色
      Radio({ value: ThemeMode.DARK, group: 'theme' })
        .checked(this.selected === ThemeMode.DARK)
        .onChange(() => {
          this.selected = ThemeMode.DARK;
          ThemeManager.setMode(ThemeMode.DARK);
        })
      Text('开启深色')

      // 关闭深色(浅色)
      Radio({ value: ThemeMode.LIGHT, group: 'theme' })
        .checked(this.selected === ThemeMode.LIGHT)
        .onChange(() => {
          this.selected = ThemeMode.LIGHT;
          ThemeManager.setMode(ThemeMode.LIGHT);
        })
      Text('关闭深色')
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .backgroundColor($r('app.color.bg_page'))
    .fontColor($r('app.color.text_main'))
  }
}

最后就是如果要记住上一次用户的选择,还可以做Preferences持久化配置,基本步骤就是这样了,希望可以帮到你

很简单通过onConfigurationUpdate监听系统深浅色变化,onCreate中获取系统深浅色设置初始值代码如下:

export class selfAbility extends UIAbility {
  //系统深浅色模式发生变化后会走这个方法
  onConfigurationUpdate(config: Configuration) {
    if (config.colorMode !== undefined) {
      //在这里可以将系统模式设置到自己定义的代码里,我这里只是展示
      console.log(JSON.stringify(config.colorMode));
    }
  }
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { 
    const config = this.context.config; 
    // 判断是否为深色模式,根据自己的代码写自己的逻辑,我这里是设置到AppStorage里了
    const isDarkMode =      config.colorMode===ConfigurationConstant.ColorMode.COLOR_MODE_DARK;
    AppStorage.setOrCreate('currentColorMode', isDarkMode); 
  }
}

适配深浅色模式可以分为下面两种情况:

应用跟随系统的深浅色模式

应用主动设置深浅色模式

具体可以参考应用深浅色适配

在HarmonyOS Next中,用户可通过“设置 > 显示和亮度 > 深色模式”开启,或从控制中心快捷切换。开发者可通过@ohos.systemtheme模块的getSystemTheme()获取当前主题,并在aboutToAppear中注册on('systemThemeChange')监听变化;UI适配建议使用@media (prefers-color-scheme: dark)媒体查询。

在 HarmonyOS Next 中,可通过窗口对象的 setColorMode() 控制深色模式,三种状态对应 ColorMode 枚举:

  • 跟随系统:ColorMode.FOLLOW_UP
  • 强制深色:ColorMode.DARK
  • 强制浅色:ColorMode.LIGHT

实现步骤:

  1. 存储用户选择(如使用 @StoragePropPreferences)。
  2. EntryAbilityonWindowStageCreate 中获取主窗口并设置颜色模式。
  3. 当用户切换选项时,再次调用 setColorMode 并保存偏好。

示例关键代码:

onWindowStageCreate(windowStage: window.WindowStage): void {
  windowStage.getMainWindow().then((win) => {
    let mode: window.ColorMode = window.ColorMode.FOLLOW_UP;
    // 读取用户保存的状态,例如 AppStorage.Get('darkMode')
    // 根据值设置 mode 为 DARK / LIGHT / FOLLOW_UP
    win.setColorMode(mode);
  });
}

切换时只需获取主窗口重新调用 setColorMode 即可即时生效,无需重启应用。

回到顶部