harmonyos 鸿蒙next换皮肤如何实现

harmonyos 鸿蒙的换肤如何实现 深浅好说,其它的比如红绿蓝好像不是很好弄

1 回复

更多关于harmonyos 鸿蒙next换皮肤如何实现的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


HarmonyOS Next 换肤功能详细实现

下面我将提供更详细的代码实现步骤,包括 currentColorMode 的详细说明和完整的可运行示例。

一、currentColorMode 详解

currentColorMode 是 HarmonyOS 中表示当前系统颜色模式的枚举值,定义在 Configuration 类中:

enum ColorMode {
  COLOR_MODE_NOT_SET = -1,  // 未设置
  COLOR_MODE_LIGHT = 0,     // 浅色模式
  COLOR_MODE_DARK = 1       // 深色模式
}

二、完整实现步骤

1. 创建项目结构

resources/
  ├── base/
  │   ├── element/
  │   │   └── color.json (浅色模式颜色)
  │   └── media/
  │       └── logo.png (浅色模式logo)
  └── dark/
      ├── element/
      │   └── color.json (深色模式颜色)
      └── media/
          └── logo.png (深色模式logo)
src/main/ets/
  ├── pages/
  │   └── Index.ets
  └── ability/
      └── MyAbilityStage.ts

2. 配置颜色资源

base/element/color.json (浅色模式):

{
  "color": [
    {
      "name": "background_color",
      "value": "#FFFFFF"
    },
    {
      "name": "text_color",
      "value": "#000000"
    },
    {
      "name": "primary_color",
      "value": "#2196F3"
    }
  ]
}

dark/element/color.json (深色模式):

{
  "color": [
    {
      "name": "background_color",
      "value": "#121212"
    },
    {
      "name": "text_color",
      "value": "#FFFFFF"
    },
    {
      "name": "primary_color",
      "value": "#64B5F6"
    }
  ]
}

3. 实现 AbilityStage

MyAbilityStage.ts:

import AbilityStage from '@ohos.app.ability.AbilityStage';
import Configuration from '@ohos.app.ability.Configuration';
import AppStorage from '@ohos.app.storage.AppStorage';

export default class MyAbilityStage extends AbilityStage {
  onCreate(): void {
    console.log('AbilityStage onCreate');
    // 初始化存储当前颜色模式
    AppStorage.setOrCreate('currentColorMode', this.context.config.colorMode);
  }

  onConfigurationUpdate(newConfig: Configuration): void {
    console.log('AbilityStage onConfigurationUpdate');
    // 当系统颜色模式变化时更新存储
    AppStorage.setOrCreate('currentColorMode', newConfig.colorMode);
  }
}

4. 实现主页面

Index.ets:

import { ColorMode } from '@ohos.app.ability.Configuration';
import AppStorage from '@ohos.app.storage.AppStorage';

@Entry
@Component
struct Index {
  @State currentMode: ColorMode = AppStorage.get('currentColorMode') || ColorMode.COLOR_MODE_LIGHT;

  aboutToAppear() {
    // 监听颜色模式变化
    AppStorage.link('currentColorMode', this, 'currentMode');
  }

  build() {
    Column() {
      // 显示当前模式
      Text(`当前模式: ${this.currentMode === ColorMode.COLOR_MODE_LIGHT ? '浅色' : '深色'}`)
        .fontSize(20)
        .fontColor($r('app.color.text_color'))
        .margin(10)

      // 显示主题图片
      Image($r('app.media.logo'))
        .width(100)
        .height(100)
        .margin(10)

      // 切换模式按钮
      Button('切换模式')
        .width(150)
        .height(40)
        .backgroundColor($r('app.color.primary_color'))
        .onClick(() => {
          // 切换系统颜色模式
          const newMode = this.currentMode === ColorMode.COLOR_MODE_LIGHT 
            ? ColorMode.COLOR_MODE_DARK 
            : ColorMode.COLOR_MODE_LIGHT;
          try {
            globalThis.abilityContext.setConfiguration({
              colorMode: newMode
            });
          } catch (err) {
            console.error(`setConfiguration failed, code is ${err.code}, message is ${err.message}`);
          }
        })
    }
    .width('100%')
    .height('100%')
    .backgroundColor($r('app.color.background_color'))
  }
}

三、运行说明

  1. 初始运行:应用启动时会根据系统当前的颜色模式显示对应的主题

  2. 切换模式

    • 点击"切换模式"按钮会调用 setConfiguration 更改系统颜色模式
    • 系统会触发 onConfigurationUpdate 回调
    • AppStorage 中的 currentColorMode 会自动更新
    • 页面会自动重新渲染应用新的颜色资源
  3. 资源加载

    • 所有 $r('app.color.xxx') 会根据当前模式自动加载对应资源
    • 图片资源也会根据模式自动加载 base/mediadark/media 下的图片

四、动态换肤扩展实现

如果需要实现更多主题(不只是深浅色),可以使用资源叠加(Overlay)方式:

  1. 创建主题资源包 (HSP)
  2. 在代码中动态加载:
import overlay from '@ohos.resources.overlay';

// 加载主题包
async function loadTheme(themeId: number) {
  try {
    await overlay.applyOverlay(this.context.resourceManager, themeId);
  } catch (err) {
    console.error(`applyOverlay failed, code is ${err.code}, message is ${err.message}`);
  }
}
回到顶部