目录

Configuring In-Application Theme Skinning

Overview

For applications developed with ArkTS, you can switch themes within the application, such as toggling between dark and light modes or changing the skin. Note that this feature is limited to in-application use and does not apply at the UIAbility or window level. It is not available for the C API and Node-API.

Customizing Theme Colors

To implement theme switching for your application, you must define custom theme colors. Use CustomTheme to specify the colors you wish to modify. Its properties are optional. Only values that need to be changed from system defaults should be specified. Unmodified values inherit from the system's default settings. For details, see System Default Token Color Values. The following is an example of how to define custom theme colors:

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

export class AppColors implements CustomColors {
  // Customize the theme color.
  public brand: ResourceColor = '#FF75D9';
  // Use $r to set different colors for the level-1 warning color in dark and light modes.
  public warning: ResourceColor = $r('sys.color.ohos_id_color_warning');
}

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

export let gAppTheme: CustomTheme = new AppTheme();

Setting Custom Theme Colors for Application Components

Setting a Custom Theme Style for Specific Application Pages

You can use WithTheme to apply the color scheme of a custom theme to the default styles of internal components. Within the scope of WithTheme, the color scheme of components will be adjusted according to the theme's color scheme.

When using WithTheme in the custom node BuilderNode, to ensure correct display, you must manually pass system environment change events to trigger a full update of the node. For details, see updateConfiguration for BuilderNode system environment change updates.

As demonstrated in the example, WithTheme({ theme: this.customTheme }) applies the custom theme styling to all components within its scope. Theme styles can be dynamically updated by modifying this.customTheme. The onWillApplyTheme callback enables a custom component to obtain the currently active Theme object.

import { CustomColors, CustomTheme, Theme } from '@kit.ArkUI';
import { common } from '@kit.AbilityKit';
// Replace $r('app.color.xxx') with the actual resource file.
class AppColors implements CustomColors {
  public fontPrimary: ResourceColor = $r('app.color.brand_purple');
  public backgroundEmphasize: ResourceColor = $r('app.color.brand_purple');
}

class AppColorsSec implements CustomColors {
  public fontPrimary: ResourceColor = $r('app.color.brand');
  public backgroundEmphasize: ResourceColor = $r('app.color.brand');
}

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

class AppThemeSec implements CustomTheme {
  public colors: AppColors = new AppColorsSec();
}

@Entry
@Component
struct DisplayPage1 {
  @State customTheme: CustomTheme = new AppTheme();
  // Replace $r('app.string.SetCustomThemeStyle') with the actual resource file. In this example, the value of the resource file is "Set a custom theme style for a local page in the Settings application".
  @State message: ResourceStr = $r('app.string.SetCustomThemeStyle');
  count = 0;

  build() {
    WithTheme({ theme: this.customTheme }) {
      Row(){
        Column() {
          Text('WithTheme')
            .fontSize(30)
            .margin({bottom: 10})
          Text(this.message)
            .margin({bottom: 10})
          Button('change theme').onClick(() => {
            this.count++;
            if (this.count > 1) {
              this.count = 0;
            }
            switch (this.count) {
              case 0:
                this.customTheme = new AppTheme();
                break;
              case 1:
                this.customTheme = new AppThemeSec();
                break;
              default:
                break;
            }
          })
        }
        .width('100%')
      }
      .height('100%')
      .width('100%')
    }
  }
}

Setting the Color Mode for Application Pages

Using WithTheme, you can set three color modes: following the system mode, light mode, and dark mode.

Within the scope of WithTheme, component styles adapt to the specified color mode by accessing the corresponding system and application resource values. This means that the color schemes of components are adjusted according to the chosen color mode.

In the example below, components within the scope are set to dark mode using WithTheme({ colorMode: ThemeColorMode.DARK }).

For the light and dark modes to take effect, add a dark.json resource file.

Example of the dark.json file content:

  {
    "color": [
      {
        "name": "start_window_background",
        "value": "#000000"
      }
    ]
  }
import { ThemeControl } from '@kit.ArkUI';

ThemeControl.setDefaultTheme(undefined);

@Entry
@Component
struct DisplayPage3 {
  @State message: string = 'Hello World';
  @State colorMode: ThemeColorMode = ThemeColorMode.DARK;

  build() {
    WithTheme({ colorMode: this.colorMode }) {
      Row() {
        Column() {
          Text(this.message)
            .fontSize(50)
            .fontWeight(FontWeight.Bold)
          Button('Switch ColorMode').onClick(() => {
            if (this.colorMode === ThemeColorMode.LIGHT) {
              this.colorMode = ThemeColorMode.DARK;
            } else if (this.colorMode === ThemeColorMode.DARK) {
              this.colorMode = ThemeColorMode.LIGHT;
            }
          })
        }
        .width('100%')
      }
      .backgroundColor($r('sys.color.background_primary'))
      .height('100%')
      // Extend the safe area to achieve an immersive light/dark mode change effect.
      .expandSafeArea(
        [SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.END, SafeAreaEdge.BOTTOM, SafeAreaEdge.START])
    }
  }
}

System Default Token Color Values

Token Scenario category Light Description Dark Description
theme.colors.brand Brand color #ff0a59f7 #ff317af7
theme.colors.warning Level-1 warning color #ffe84026 #ffd94838
theme.colors.alert Level-2 warning color #ffed6f21 #ffdb6b42
theme.colors.confirm Confirmation color #ff64bb5c #ff5be854
theme.colors.fontPrimary Level-1 text #e5000000 #e5ffffff
theme.colors.fontSecondary Level-2 text #99000000 #99ffffff
theme.colors.fontTertiary Level-3 text #66000000 #66ffffff
theme.colors.fontFourth Level-4 text #33000000 #33ffffff
theme.colors.fontEmphasize Highlight text #ff0a59f7 #ff317af7
theme.colors.fontOnPrimary Level-1 text inversion #ffffffff #ff000000
theme.colors.fontOnSecondary Level-2 text inversion #99ffffff #99000000
theme.colors.fontOnTertiary Level-3 text inversion #66ffffff #66000000
theme.colors.fontOnFourth Level-4 text inversion #33ffffff #33000000
theme.colors.iconPrimary Level-1 icon #e5000000 #e5ffffff
theme.colors.iconSecondary Level-2 icon #99000000 #99ffffff
theme.colors.iconTertiary Level-3 icon #66000000 #66ffffff
theme.colors.iconFourth Level-4 icon #33000000 #33ffffff
theme.colors.iconEmphasize Highlight icon #ff0a59f7 #ff317af7
theme.colors.iconSubEmphasize Highlight auxiliary icon #660a59f7 #66317af7
theme.colors.iconOnPrimary Level-1 icon inversion #ffffffff #ff000000
theme.colors.iconOnSecondary Level-2 icon inversion #99ffffff #99000000
theme.colors.iconOnTertiary Level-3 icon inversion #66ffffff #66000000
theme.colors.iconOnFourth Level-4 icon inversion #33ffffff #33000000
theme.colors.backgroundPrimary Level-1 background (solid color/opaque color) #ffffffff #ffe5e5e5
theme.colors.backgroundSecondary Level-2 background (solid color/opaque color) #fff1f3f5 #ff191a1c
theme.colors.backgroundTertiary Level-3 background (solid color/opaque color) #ffe5e5ea #ff202224
theme.colors.backgroundFourth Level-4 background (solid color/opaque color) #ffd1d1d6 #ff2e3033
theme.colors.backgroundEmphasize Highlight background (solid color/opaque color) #ff0a59f7 #ff317af7
theme.colors.compForegroundPrimary Foreground background #ff000000 #ffe5e5e5
theme.colors.compBackgroundPrimary White background #ffffffff #ffffffff
theme.colors.compBackgroundPrimaryTran White transparent background #ffffffff #33ffffff
theme.colors.compBackgroundPrimaryContrary Always-on background #ffffffff #ffe5e5e5
theme.colors.compBackgroundGray Gray background #fff1f3f5 #ffe5e5ea
theme.colors.compBackgroundSecondary Level-2 background #19000000 #19ffffff
theme.colors.compBackgroundTertiary Level-3 background #0c000000 #0cffffff
theme.colors.compBackgroundEmphasize Highlight background #ff0a59f7 #ff317af7
theme.colors.compBackgroundNeutral Black neutral highlight background #ff000000 #ffffffff
theme.colors.compEmphasizeSecondary 20% highlight background #330a59f7 #33317af7
theme.colors.compEmphasizeTertiary 10% highlight background #190a59f7 #19317af7
theme.colors.compDivider Divider color #33000000 #33ffffff
theme.colors.compCommonContrary Common inversion #ffffffff #ff000000
theme.colors.compBackgroundFocus Focused background color #fff1f3f5 #ff000000
theme.colors.compFocusedPrimary Focused level-1 inversion #e5000000 #e5ffffff
theme.colors.compFocusedSecondary Focused level-2 inversion #99000000 #99ffffff
theme.colors.compFocusedTertiary Focused level-3 inversion #66000000 #66ffffff
theme.colors.interactiveHover Common hover interactive color #0c000000 #0cffffff
theme.colors.interactivePressed Common pressed interactive color #19000000 #19ffffff
theme.colors.interactiveFocus Common focused interactive color #ff0a59f7 #ff317af7
theme.colors.interactiveActive Common active interactive color #ff0a59f7 #ff317af7
theme.colors.interactiveSelect Common selected interactive color #33000000 #33ffffff
theme.colors.interactiveClick Common clicked interactive color #19000000 #19ffffff

For details about the components that can be affected by each token color value, see Colors.