概述

HarmonyOS 7.0 引入了全新的系统材质(System Material)功能,通过 @ohos.arkui.uiMaterial 模块提供接口定义。系统材质能够为 UI 组件带来更加沉浸式、富有质感的视觉效果,包括背景颜色、边框颜色、边框宽度、阴影效果、材质模糊效果等。

系统材质在不同设备上表现存在差异,设备性能越高(如高端手机、平板、PC),材质效果越丰富;在性能较低的设备上,效果会相应简化。这种自适应特性确保了应用在各种设备上都能获得最佳的用户体验。

起始版本:26.0.0
模块状态:Beta
支持设备:Phone、PC/2in1、Tablet、TV、Wearable


一、核心概念

1.1 MaterialType - 材质类型枚举

系统材质类型枚举,定义了不同的系统材质类型。

名称 说明
IMMERSIVE 2 沉浸式材质类型。通过 MaterialInfo 接口的 type 可获知当前应用的材质类型,映射到底层功能。实际材质效果通过 ImmersiveMaterial 实现。

起始版本:26.0.0
系统能力:SystemCapability.ArkUI.ArkUI.Full

1.2 MaterialState - 材质使用状态枚举

材质使用状态枚举,表示应用是否启用沉浸式系统材质设置的状态。

名称 说明
DEFAULT 0 默认模式。弹窗(Dialog、Toast、AlphabetIndexer等)未设置背景颜色时,默认开启沉浸式系统材质;Text组件copyOption长按或双击弹出文本菜单默认开启沉浸式系统材质;其他组件默认不启用。
ENABLE 1 启用模式。弹窗(Dialog、Toast、AlphabetIndexer、Select菜单、Toggle、SegmentButton、SegmentButtonV2、bindSheet等)默认开启沉浸式系统材质;Text组件copyOption长按或双击弹出文本菜单默认开启沉浸式系统材质。此模式下,沉浸式系统材质样式效果优先级高于开发者设置的背景颜色、材质、阴影和边框样式,开发者开启后无需再设置。
DISABLE 2 禁用模式。所有组件禁止使用沉浸式系统材质,使用此值为应用禁用沉浸式系统材质,也不会有效果。

起始版本:26.0.0

1.3 ImmersiveStyle - 沉浸式材质样式枚举

沉浸式材质样式枚举。不同的材质样式对应不同的材质参数,需要根据材质的模糊程度、高度或效果强度来选择。

名称 说明
ULTRA_THIN 0 超薄样式,材质层超薄且有很强透光效果
THIN 1 薄样式,材质层薄且有较强透光效果
REGULAR 2 常规样式,材质层的厚度适中
THICK 3 厚样式,模糊效果强
ULTRA_THICK 4 超厚样式,模糊效果更强

起始版本:26.0.0


二、核心接口

2.1 MaterialInfo - 材质信息接口

材质信息接口,包含材质使用状态和材质类型。

属性 类型 只读 可选 说明
state MaterialState 材质使用状态
type MaterialType 材质类型标识,表示当前枚举对应的材质类型。值为枚举类型,表示映射到底层功能

起始版本:26.0.0

2.2 ImmersiveOptions - 沉浸式材质选项

沉浸式材质参数。

属性 类型 只读 可选 说明
style ImmersiveStyle 沉浸式样式,不同样式对应不同材质参数,影响材质的厚度和效果。说明:该参数依赖设备能力,不同设备显示效果可能不同。默认值:ImmersiveStyle.REGULAR
materialColor ResourceColor 材质层赋色,用于改变材质层的颜色。在高端设备上,设置该参数为 undefined 时,材质层会呈现上层颜色效果;设置该参数为有效颜色值时,材质层为该颜色和上层颜色混合效果。在低端设备上,设置该参数为 undefined 时,效果为设备系统默认的背景颜色效果;设置该参数为有效颜色值时,该参数为背景颜色 backgroundColor 的值。说明:该参数依赖设备能力,不同设备显示效果可能不同。默认值:undefined
colorInvert boolean 是否对材质层背景节点内的文字颜色自动反色。值为 false 则不会自动反色;值为 true 时,只有材质层足够薄时才会自动反色。能自动反色的材质有系统材质,沉浸式材质样式为 THIN 或 ULTRA_THIN 时。应用的长按、选中、聚焦的强交互场景,越靠近用户层级,越容易触发反色。反色效果需要自定义颜色时,可以在对应接口设置颜色值时生效。效果越靠近背景层,效果越弱。可设置颜色的接口:Text组件的 fontColor、Button组件的 fontColor、SymbolGlyph组件的 fontColor、Image组件的 fillColor、Search组件的 placeholderColor、fontColor、searchIcon 中的图标颜色、cancelButton 中的图标颜色、caretStyle 中的光标颜色、TabContent组件的 tabBar 使用 BottomTabBarStyle 样式时的文本、图标颜色。说明:该参数依赖设备能力,不同设备显示效果可能不同。默认值:false
applyShadow boolean 是否添加材质层的阴影效果。该参数为 true 时,组件中的阴影效果都生效,包括 shadow 通用属性;该参数为 false 时,shadow 通用属性不生效,材质层的阴影效果不生效。说明:该参数依赖设备能力,不同设备显示效果可能不同。默认值:true
interactive boolean 是否为该材质层添加交互反馈效果。说明:该参数依赖设备能力,不同设备显示效果可能不同。默认值:false
lightEffect LightEffectOptions? | null 是否为该材质层添加光交互反馈效果。该参数为 null 时,不添加光交互反馈效果。说明:该参数依赖设备能力,不同设备显示效果可能不同。默认值:undefined,不添加光交互反馈效果

起始版本:26.0.0

2.3 LightEffectOptions - 光交互反馈效果配置

沉浸式材质的光交互反馈效果配置,可自定义反射光中的颜色。

属性 类型 只读 可选 说明
color ResourceColor 自定义反射光中的颜色。默认值:Color.White

起始版本:26.0.0


三、核心类

3.1 Material - 系统材质基类

系统材质基类。

起始版本:26.0.0
系统能力:SystemCapability.ArkUI.ArkUI.Full

静态属性

empty

static get empty(): Material

返回空材质对象,用于关闭某个组件的沉浸式系统材质效果。使用方式为 uiMaterial.Material.empty

在 enable 模式下,可以通过设置 systemMaterial(uiMaterial.Material.empty) 来关闭某个组件的某个沉浸式系统材质效果。如果该组件未支持关闭沉浸式系统材质接口,则无法通过此方法关闭材质效果。

起始版本:26.0.0

3.2 ImmersiveMaterial - 沉浸式材质类

沉浸式材质类,继承自 Material。沉浸式材质根据设备性能有分级的表现,设备性能越高、内存越大的设备,呈现的系统材质效果越丰富。在高端设备上,影响材质的模糊、材质层颜色、阴影效果、材质层背景颜色效果;通过 systemMaterial 设置效果后,设置的背景颜色 backgroundColor 会被覆盖为透明色,设置的边框宽度 borderWidth 会被覆盖为无边框效果。在低端设备上,影响背景颜色 backgroundColor、边框颜色 borderColor、边框宽度 borderWidth、阴影 shadow 效果、材质层背景颜色效果。同一材质效果可能会受到应用场景、组件层级、背景颜色、背景材质等因素影响,不同强度层次的材质在同一场景下,实际的材质效果存在差异。

构造函数
constructor(options?: ImmersiveOptions)

ImmersiveMaterial 的构造函数。

参数

参数名 类型 必填 说明
options ImmersiveOptions 系统材质构造选项,包括沉浸式样式、材质层赋色等。默认值:参考 ImmersiveOptions 接口各参数的默认值,即 {style: ImmersiveStyle.REGULAR, materialColor: undefined, colorInvert: false, applyShadow: true, interactive: false, lightEffect: undefined}

起始版本:26.0.0


四、API 方法

4.1 getMaterialInfo - 获取材质信息

getMaterialInfo(): MaterialInfo

获取当前应用的材质配置信息,返回的信息根据应用在 module.json5 中设置的 metadata 来。

返回值

类型 说明
MaterialInfo 返回当前应用的材质配置信息,包含材质使用状态和材质类型

起始版本:26.0.0


五、接入教程

5.1 基础配置

module.json5 文件中设置材质信息配置(注意:只有 entry 类型的 module 设置该配置才会生效):

{
  "module": {
    "type": "entry",
    "metadata": [{
      "name": "ohos.arkui.UIMaterial.state",
      "value": "enable"
    }]
  }
}

5.2 导入模块

import { uiMaterial } from '@kit.ArkUI';

六、使用示例

示例 1:设置沉浸式系统材质

此示例展示如何创建沉浸式材质的 ImmersiveMaterial 对象,并通过 systemMaterial 属性设置该材质。

从 API 版本 26.0.0 开始,支持 ImmersiveMaterial 的 systemMaterial 属性。

import { uiMaterial } from '@kit.ArkUI';

@Entry
@Component
struct SystemMaterialPage {
  build() {
    Column() {
      Stack() {
        Image($r('app.media.bg1'))
          .width('100%')
          .height('100%')

        Column({ space: 30 }) {
          Column() {
            Text("ULTRA_THIN")
          }
          .width(328)
          .height(56)
          .borderRadius(28)
          .justifyContent(FlexAlign.Center)
          .alignItems(HorizontalAlign.Center)
          .systemMaterial(new uiMaterial.ImmersiveMaterial({
            style: uiMaterial.ImmersiveStyle.ULTRA_THIN,
          }))

          Column() {
            Text("THIN")
          }
          .width(328)
          .height(56)
          .borderRadius(28)
          .justifyContent(FlexAlign.Center)
          .alignItems(HorizontalAlign.Center)
          .systemMaterial(new uiMaterial.ImmersiveMaterial({
            style: uiMaterial.ImmersiveStyle.THIN,
          }))

          Column() {
            Text("REGULAR")
          }
          .width(328)
          .height(56)
          .borderRadius(28)
          .justifyContent(FlexAlign.Center)
          .alignItems(HorizontalAlign.Center)
          .systemMaterial(new uiMaterial.ImmersiveMaterial({
            style: uiMaterial.ImmersiveStyle.REGULAR,
          }))

          Column() {
            Text("THICK")
          }
          .width(328)
          .height(56)
          .borderRadius(28)
          .justifyContent(FlexAlign.Center)
          .alignItems(HorizontalAlign.Center)
          .systemMaterial(new uiMaterial.ImmersiveMaterial({
            style: uiMaterial.ImmersiveStyle.THICK,
          }))

          Column() {
            Text("ULTRA_THICK")
          }
          .width(328)
          .height(56)
          .borderRadius(28)
          .justifyContent(FlexAlign.Center)
          .alignItems(HorizontalAlign.Center)
          .systemMaterial(new uiMaterial.ImmersiveMaterial({
            style: uiMaterial.ImmersiveStyle.ULTRA_THICK,
          }))
        }
      }
      .height('90%')
      .width('90%')
    }
    .height('100%')
    .width('100%')
    .alignItems(HorizontalAlign.Center)
    .justifyContent(FlexAlign.Center)
  }
}

效果说明

  • 在低端设备上表现:背景色填充,无边框效果
    在这里插入图片描述

  • 在中端设备上表现:背景模糊效果,有边框效果
    在这里插入图片描述

  • 在高端设备上表现:材质模糊效果,透明背景,无边框效果

  • 在这里插入图片描述

示例 2:获取材质配置信息并使用空材质关闭沉浸式系统材质

此示例展示如何通过 uiMaterial.getMaterialInfo 获取当前应用的材质配置信息,并根据材质状态使用 empty 关闭某个组件的某个沉浸式系统材质效果。

从 API 版本 26.0.0 开始,支持 uiMaterial.getMaterialInfo 接口和 empty 对象。

步骤 1:在 module.json5 文件中设置材质信息配置(注意:只有 entry 类型的 module 设置该配置才会生效)

{
  "module": {
    "type": "entry",
    "metadata": [{
      "name": "ohos.arkui.UIMaterial.state",
      "value": "enable"
    }]
  }
}

步骤 2:编写业务代码

import { uiMaterial } from '@kit.ArkUI';

@Entry
@Component
struct MaterialInfoPage {
  private info: uiMaterial.MaterialInfo = uiMaterial.getMaterialInfo();

  build() {
    Column() {
      Text(`MaterialState: ${this.info.state}`)
        .fontSize(16)
        .margin({ bottom: 10 })
      Text(`MaterialType: ${this.info.type}`)
        .fontSize(16)
        .margin({ bottom: 20 })

      if (this.info.state === uiMaterial.MaterialState.ENABLE) {
        Button('Enable UiMaterial')
          .backgroundColor(Color.Transparent)
          .systemMaterial(new uiMaterial.ImmersiveMaterial({
            style: uiMaterial.ImmersiveStyle.ULTRA_THIN
          }))
          .fontColor(Color.Blue)
          .margin({ bottom: 10 })

        Select([
          {value: 'select item'}
        ]).value('select item')
        .margin({ bottom: 10 })

        Select([
          {value: 'select item'}
        ]).value('select item')
        .systemMaterial(uiMaterial.Material.empty)
      }
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .backgroundImage($r('app.media.img'))
    .backgroundImageSize(ImageSize.FILL)
  }
}

效果说明

  • 在高端设备上表现:材质模糊效果,背景透明

示例 3:添加材质层的交互反馈效果

此示例展示如何通过 ImmersiveOptions 中的 interactive 接口实现材质层的交互反馈效果。

从 API 版本 26.0.0 开始,支持 interactive 接口。

import { uiMaterial } from '@kit.ArkUI'

@Entry
@Component
struct Index {
  build() {
    Stack() {
      Image($r('app.media.startIcon'))
      Column() {
        Column() {
          Text("Context")
        }
        .margin({ bottom: 100 })
        .width(248)
        .height(56)
        .borderRadius(28)
        .justifyContent(FlexAlign.Center)
        .alignItems(HorizontalAlign.Center)
        .systemMaterial(new uiMaterial.ImmersiveMaterial({
          style: uiMaterial.ImmersiveStyle.ULTRA_THIN,
          interactive: true,
        }))
      }
      .height('100%')
      .width('100%')
      .justifyContent(FlexAlign.Center)
    }
  }
}

效果说明

  • 点击材质层时会有交互反馈效果(如高亮、波纹等)

示例 4:添加材质层的光交互反馈效果

此示例展示如何通过 ImmersiveOptions 中的 lightEffect 接口实现材质层光交互反馈效果。

从 API 版本 26.0.0 开始,支持 lightEffect 接口。

import { uiMaterial } from '@kit.ArkUI';

@Entry
@Component
struct LightEffect {
  @State itemsKey: number[] = [0, 1, 2];
  @State circleRadius: number = 40;
  @State spaceValue: number = 10;
  @State myMaterial: uiMaterial.Material = new uiMaterial.ImmersiveMaterial({
    style: uiMaterial.ImmersiveStyle.ULTRA_THIN,
    interactive: true,
    lightEffect: { color: undefined },
  });

  build() {
    Column() {
      Row() {
        Text("标题")
          .flexGrow(2)
          .fontColor(Color.White)
        Row({ space: this.spaceValue }) {
          ForEach(this.itemsKey, (item: number, index: number) => {
            Row()
              .width(this.circleRadius * 2)
              .height(this.circleRadius * 2)
              .borderRadius(this.circleRadius)
              .systemMaterial(this.myMaterial)
          })
        }
      }
      .justifyContent(FlexAlign.End)
      .backgroundColor(Color.Black)
      .width('100%')
      .padding(20)
    }
    .height('100%')
    .width('100%')
  }
}

效果说明

  • 材质层会显示光交互反馈效果,可通过 lightEffect.color 自定义反射光颜色

七、效果对比

7.1 不同设备上的表现差异

设备类型 背景效果 边框效果 模糊效果 阴影效果
低端设备 背景色填充 有边框 无模糊 有阴影
中端设备 背景模糊 有边框 有模糊 有阴影
高端设备 透明背景 无边框 材质模糊 有阴影

7.2 不同样式等级的效果差异

样式 透光度 模糊强度 适用场景
ULTRA_THIN 极高 极弱 需要强透光效果的场景,如悬浮提示
THIN 需要较强透光效果的场景,如轻量级弹窗
REGULAR 适中 适中 常规场景,如按钮、卡片
THICK 需要强模糊效果的场景,如对话框
ULTRA_THICK 极低 极强 需要极强模糊效果的场景,如模态窗口

八、最佳实践

8.1 选择合适的材质样式

  1. ULTRA_THIN / THIN:适用于需要强透光效果的场景,如悬浮提示、轻量级弹窗、工具栏等
  2. REGULAR:适用于常规场景,如按钮、卡片、列表项等
  3. THICK / ULTRA_THICK:适用于需要强模糊效果的场景,如对话框、模态窗口、重要提示等

8.2 配置建议

  1. 启用交互反馈:对于可交互的组件(如按钮),建议设置 interactive: true 以提供更好的用户体验
  2. 启用光效果:在需要突出交互反馈的场景,可以设置 lightEffect 以增强视觉效果
  3. 关闭阴影:在某些扁平化设计场景,可以设置 applyShadow: false 以去除阴影效果

8.3 性能优化

  1. 合理选择样式等级:根据实际需求选择合适的材质样式,避免过度使用高强度模糊效果
  2. 设备适配:系统会根据设备性能自动调整效果,开发者无需手动处理设备差异
  3. 按需启用:只在需要的组件上启用系统材质,避免全局滥用

九、注意事项

  1. 版本要求:系统材质功能从 API 版本 26.0.0 开始支持,请确保项目配置的 API 版本不低于此版本
  2. 模块类型:材质配置只在 entry 类型的 module 中生效
  3. Beta 状态:当前模块处于 Beta 状态,API 可能会在后续版本中调整
  4. 设备差异:不同设备上的表现存在差异,建议在多种设备上进行测试
  5. 资源引用:示例中的图片资源(如 $r('app.media.bg1'))需要替换为实际项目中的图片资源文件

十、总结

HarmonyOS 7.0 的系统材质功能为开发者提供了一套强大的 UI 质感解决方案,通过简单的配置即可实现丰富的视觉效果。系统材质的自适应特性确保了应用在各种设备上都能获得最佳的用户体验,大大降低了开发者的适配成本。

通过本指南,开发者可以快速掌握系统材质的使用方法,并根据实际需求选择合适的材质样式和配置参数,为用户打造更加沉浸式、富有质感的应用界面。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐