有没有HarmonyOS鸿蒙Next类似设置color_primary配置后能全局影响控件默认的主题色

有没有HarmonyOS鸿蒙Next类似设置color_primary配置后能全局影响控件默认的主题色 有没有类似设置color_primary 配置后 能全局影响控件默认的主题色

7 回复

1. 使用 ThemeControl.setDefaultTheme 设置应用级全局主题

  • 通过 ThemeControl.setDefaultTheme 方法,可以在应用启动时(如在 onWindowStageCreate 阶段)设置一个自定义主题(CustomTheme),该主题会作为应用级的默认主题,影响所有组件的颜色风格(如背景色、字体色等)。
  • 关键步骤
    • 定义自定义主题类(实现 CustomColors 接口),覆写需要修改的颜色属性(如 brandfontPrimarybackgroundPrimary 等)。未修改的属性会继承系统默认值。
    • 调用 ThemeControl.setDefaultTheme() 应用该主题。
  • 示例代码(V1/V2 组件均支持):
import { CustomTheme, CustomColors, ThemeControl } from '@kit.ArkUI';

// 自定义颜色
class BlueColors implements CustomColors {
  fontPrimary = Color.White;  // 影响文本主色
  backgroundPrimary = Color.Blue; // 影响背景主色
  brand = Color.Blue; // 影响品牌色
}

class PageCustomTheme implements CustomTheme {
  colors?: CustomColors;
  constructor(colors: CustomColors) {
    this.colors = colors;
  }
}

// 设置全局默认主题
const BlueColorsTheme = new PageCustomTheme(new BlueColors());
ThemeControl.setDefaultTheme(BlueColorsTheme); // 此调用后,所有组件默认使用 BlueColorsTheme 的颜色

2. 通过配置文件指定系统主题(如深色/浅色模式)

  • module.json5 中通过 systemTheme 标签指定应用使用的系统主题配置文件(如 theme_config.json),从而全局控制深浅色模式(从 API Version 20 开始支持)。
  • 示例:
// module.json5
{
  "module": {
    "systemTheme": "$profile:theme_config" // 指向 profile/theme_config.json
  }
}

// resources/base/profile/theme_config.json
{
  "systemTheme": "$ohos:theme:ohos_theme" // 使用系统默认主题
}

3. 使用 WithTheme 组件进行局部主题覆盖

  • 如果需要对特定区域设置独立主题,可以使用 WithTheme 组件包裹子组件,通过 theme 属性传入自定义主题,或通过 colorMode 指定深浅色模式。但这不是全局方法,仅影响局部。

更多关于有没有HarmonyOS鸿蒙Next类似设置color_primary配置后能全局影响控件默认的主题色的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


可以实现的话,​​​​关键步骤和代码你可以看看我的代码:​​

  1. ​​定义自定义主题色 (AppTheme.ets):​​

    • 创建 AppColors类实现 CustomColors接口。
    • 在 AppColors中声明要覆盖的系统默认颜色 token(如 brand, warning),并赋予新的 ResourceColor值。
    • 创建 AppTheme类实现 CustomTheme接口,其 colors属性指向 AppColors的实例。
    • 导出 AppTheme的实例 gAppTheme供其他模块使用。
// AppTheme.ets
import { CustomColors, CustomTheme } from '@kit.ArkUI';

export class AppColors implements CustomColors {
  brand: ResourceColor = '#FF75D9'; // 覆盖品牌色
  warning: ResourceColor = $r('app.color.start_window_background'); // 覆盖警告色(支持深/浅色模式)
}

export class AppTheme implements CustomTheme {
  public colors: AppColors = new AppColors();
}

export let gAppTheme: CustomTheme = new AppTheme(); // 导出主题实例
  1. ​在页面中应用自定义主题色 (Index.ets):​

    • ​关键点:​​ 必须在页面 build()方法执行​​之前​​设置主题。
    • 使用 ThemeControl.setDefaultTheme(gAppTheme)设置应用组件的默认主题。
    • 在自定义组件(如 DisplayPage)中实现 onWillApplyTheme(theme: Theme)生命周期方法。此方法在主题应用前被调用,参数 theme包含当前生效的主题对象。
    • onWillApplyTheme中,可以从 theme.colors获取最新的颜色值(如 theme.colors.backgroundPrimary),并更新组件的状态变量(如 this.menuItemColor)。
    • build()方法中,使用这些状态变量设置组件的样式(如 .backgroundColor(this.menuItemColor))。
// Index.ets (关键部分)
import { Theme, ThemeControl } from '@kit.ArkUI';
import { gAppTheme } from './AppTheme';

// 在页面build前设置主题 !!!
ThemeControl.setDefaultTheme(gAppTheme);

[@Entry](/user/Entry)
[@Component](/user/Component)
struct DisplayPage {
  @State menuItemColor: ResourceColor = $r('sys.color.background_primary'); // 初始值

  onWillApplyTheme(theme: Theme) { // 主题应用前的回调
    this.menuItemColor = theme.colors.backgroundPrimary; // 获取并更新主题色
  }

  build() {
    Column() {
      // ... 组件树 ...
      ListItem() {
        Column() {
          // ... 内容 ...
        }
        .backgroundColor(this.menuItemColor) // 使用动态主题色
      }
      // ... 更多组件 ...
    }
  }
}
  1. ​在 UIAbility (应用入口) 中应用自定义主题色 (EntryAbility.ets):​

    • ​关键点:​​ 必须在 windowStage.loadContent的​​完成回调​​中设置主题,确保 ArkUI 框架已初始化。
    • onWindowStageCreate方法中,调用 windowStage.loadContent加载页面。
    • loadContent的回调函数内部,使用 ThemeControl.setDefaultTheme({ colors: abilityThemeColors })设置主题。可以直接内联定义 CustomColors或使用预先定义好的对象(如 abilityThemeColors)。
// EntryAbility.ets (关键部分)
import { window, CustomColors, ThemeControl } from '@kit.ArkUI';

class AppColors implements CustomColors { // 也可以在这里定义
  fontPrimary = 0xFFD53032;
  // ... 其他覆盖的颜色 ...
}
const abilityThemeColors = new AppColors();

export default class EntryAbility extends UIAbility {
  onWindowStageCreate(windowStage: window.WindowStage) {
    windowStage.loadContent('pages/Index', (err, data) => {
      if (err.code) { ... return; }
      // 在loadContent回调中设置主题 !!!
      ThemeControl.setDefaultTheme({ colors: abilityThemeColors });
    });
  }
}

​​主要一些注意事项:​​

  • ​​继承性:​​ 在 CustomColors中只声明需要修改的颜色 token。未声明的 token 会自动继承系统的默认值。
  • ​​资源引用 ($r):​​ 使用 $r(‘app.color.xxx’)引用应用资源,可以方便地实现深色/浅色模式适配(在 resources目录下定义不同模式的值)。
  • ​​设置时机 (setDefaultTheme):​​
    • 在页面中:​​必须​​在 @Component的 build()方法执行​​之前​​调用(通常在 @Entry下方)。
    • 在 UIAbility 中:​​必须​​在 windowStage.loadContent的​​完成回调​​中调用。
  • ​​恢复默认:​​ 调用 ThemeControl.setDefaultTheme(undefined)会使所有组件恢复使用系统默认的 token 颜色值。

配置主题色

(代码中的颜色资源自己配置,并且支持*动态修改主题色。如果只需要进入系统之后改变一次主题色,只需要在下方代码中创建一个CustomColors实现类,并配置系统对应的属性值*即可)

import { CustomColors, CustomTheme } from '@kit.ArkUI'
import { HashMap } from '@kit.ArkTS'


/* 主题定义 多个主题就创建多个*/
/* 鸿蒙蓝(星河蓝) blueAppTheme */
// 主题颜色
class BlueAppThemeColors implements CustomColors {
  iconEmphasize: ResourceColor = $r('sys.color.icon_emphasize')
}
// 主题配置
class BlueAppTheme implements CustomTheme {
  public colors: BlueAppThemeColors = new BlueAppThemeColors()
}

/* 哔哩粉 pinkAppTheme */
// 主题颜色
class PinkAppThemeColors implements CustomColors {
  iconEmphasize: ResourceColor = $r('app.color.theme_color_main_pink')
}
// 主题配置
class PinkAppTheme implements CustomTheme {
  public colors: PinkAppThemeColors = new PinkAppThemeColors()
}


/* 导出 */
// 自定义主题名称 TODO 补充主题名称字符串
export type CustomThemeName = 'blueAppTheme' | 'pinkAppTheme'
// 自定义主题HashMap
let _CUSTOM_THEME_MAP: HashMap<CustomThemeName, CustomTheme> = new HashMap<CustomThemeName, CustomTheme>()
_CUSTOM_THEME_MAP.set('blueAppTheme', new BlueAppTheme())
_CUSTOM_THEME_MAP.set('pinkAppTheme', new PinkAppTheme())

export const CUSTOM_THEME_MAP = _CUSTOM_THEME_MAP

在启动页初始化获取当前主题色配置

// 主题色(示例中主题配置里配置了一个颜色,所以只用`ResourceColor`变量来接收色值,如果有多个颜色,就把这个变量换成`CustomTheme`类型的变量)
@Provide('icon_emphasize')
icon_emphasize: ResourceColor = $r('sys.color.icon_emphasize')


/**
 * 获取当前组件上下文的Theme对象,在build()函数之前执行。
 * @param theme
 */
onWillApplyTheme(theme: Theme) {
  hilog.info(0x1000, this.componentName, `#onWillApplyTheme`)
  this.icon_emphasize = theme.colors.iconEmphasize
}

使用

/* 主题色 */
@Consume('icon_emphasize') icon_emphasize: ResourceColor

build(){
  Text('示例文本')
    .fontColor(this.icon_emphasize)
}

动态更改主题色

/**
   * 更改主题配置
   * @param customThemeName 自定义主题的名字
   */
function changeThemeColor(customThemeName: CustomThemeName) {
  ThemeControl.setDefaultTheme(CUSTOM_THEME_MAP.get(customThemeName))
}

可以的,我以前写过。就是配置主题色官方文档中也有示例代码。明天我再来看没人回答你的话我把代码贴给你,现在没电脑。

HarmonyOS Next的主题色配置通过资源管理系统实现。在resources/base/element/目录下创建color.json文件,定义color_primary等颜色资源。系统级主题色需在AppScope的resources文件中配置,应用启动时自动加载。控件通过引用$color:color_primary即可统一应用主题色。主题色变更会通过资源ID关联自动更新所有使用该资源的控件,无需单独设置。

在HarmonyOS Next中,可以通过定义资源文件实现全局主题色配置。具体步骤如下:

  1. resources/base/element/目录下创建color.json文件,定义颜色资源:
{
  "color": {
    "color_primary": "#007DFF"
  }
}
  1. 在布局文件中引用定义的颜色资源:
<Button
  ohos:height="match_content"
  ohos:width="match_content"
  ohos:background_element="$color:color_primary"
  ohos:text="主题按钮"/>
  1. 如需动态修改主题色,可在代码中使用:
ResourceManager resManager = getResourceManager();
Element element = resManager.getElement(ResourceTable.Color_color_primary);
button.setBackground(element);

通过这种方式,修改color_primary的值即可全局影响所有使用该颜色的控件,实现统一主题色管理。建议将主要交互控件(如按钮、选中状态等)都绑定到主题色资源,便于维护和主题切换。

回到顶部