【HarmonyOS 7 沉浸光感深度实战】 03 五档 ImmersiveStyle 到底怎么选
文章目录
前言
在之前接口和开关都确认以后,普通组件已经具备显示沉浸材质的基本条件。
接下来,开发者很快就会遇到一个更具体的问题:五档 ImmersiveStyle 应该怎样选择。
ULTRA_THIN、THIN、REGULAR、THICK 和 ULTRA_THICK 的名称看起来很直观。刚开始接入时,大家通常会根据“薄”和“厚”直接做决定,例如工具栏使用薄材质,弹窗使用厚材质,页面能正常显示以后就继续开发。
我第一次比较这五档材质时,也采用过这种方式。后来把五张卡片放在相同背景、尺寸和文字条件下对比,我才逐渐发现,材质厚度只是选择依据之一。组件面积、所在位置、背景复杂度和前景信息量,同样会改变最终结果。
材质逐渐变厚以后,背景细节会不断减弱,前景内容会更加稳定,组件在页面中的视觉重量也会增加。搜索框使用过厚材质时,页面可能显得沉重;大面积浮层使用过薄材质时,背景内容又容易干扰文字和操作。
因此,这一轮测试继续控制变量。五张卡片使用相同的背景、尺寸、圆角和文字,只修改 ImmersiveStyle。先看清五档样式的变化,再回到搜索框、工具栏、菜单和弹窗中做选择。
目前我的测试设备还没有 HarmonyOS 7 实机测试权限,本篇先使用模拟器核对接口和基础效果。具备相应权限时,大家应优先在真机上复核材质表现。

一、五档样式的差异应该看什么
ImmersiveStyle 从 API 26.0.0 开始提供,它定义了五种沉浸式材质样式。每一种样式都对应一组系统管理的材质参数,开发者通过枚举选择整体厚度,无需自行组合模糊、高光和阴影等效果。
| 枚举值 | 材质特点 | 适合作为起点的场景 |
|---|---|---|
ULTRA_THIN |
超薄,具有很强的透明效果 | 浮动工具栏、顶部悬浮区域 |
THIN |
薄,具有较强的透明效果 | 搜索框、底部悬浮操作栏 |
REGULAR |
常规厚度,前景与背景较为均衡 | 普通卡片、通用悬浮组件 |
THICK |
厚,背景模糊效果较强 | 菜单、临时弹出的浮层 |
ULTRA_THICK |
超厚,背景模糊效果很强 | 弹窗、半模态页面 |
从这张表看,五档样式形成了一条从通透到模糊的变化路径。不过,实际观察时还要同时看背景、前景和组件本身。
第一项是背景还剩多少信息。背景中的颜色分界、图案和文字越容易辨认,材质就越轻薄。对于需要延续页面内容的悬浮工具栏,这种通透感比较重要。
第二项是前景内容是否稳定。材质变厚以后,背景对文字和图标的干扰会逐渐降低。菜单、弹窗和信息量较大的浮层,更需要稳定的前景区域。
第三项是组件在页面中显得多重。同一张卡片使用 ULTRA_THIN 时会比较轻,使用 ULTRA_THICK 时会形成更明确的层级。组件面积越大,这种视觉重量的变化通常越明显。
除了样式本身,设备能力也会影响结果。style 参数主要影响高算力和中算力设备,系统会结合设备分档调整实际表现。用户设置的沉浸光感强度也会影响透明度、对比度、折射和环境交互程度。
因此,五档材质需要在相同设备、主题和系统设置下比较。先统一观察条件,后面的选择才有参考价值。

二、组件的位置和面积为什么会改变选择
了解五档材质的基本变化以后,下一步就要把它们放回实际页面。
同一档材质用在不同位置,带来的感受会明显不同。顶部悬浮栏通常覆盖标题、图片或滚动内容,底部操作栏承载按钮、页签和播放控制。菜单可能出现在任意背景上,半模态页面又会占据更大的画面面积。
这些差异决定了组件需要保留多少背景,也决定了前景内容需要多强的稳定性。
顶部悬浮区域可以先试 ULTRA_THIN
顶部悬浮组件需要和页面内容保持连续。ULTRA_THIN 能够保留更多背景信息,让滚动内容自然延伸到顶部。
顶部悬浮组件可以优先使用 ULTRA_THIN,并结合渐变模糊延展内容区域。背景中存在大量文字或高对比图案时,可以继续比较 THIN,重点检查标题与图标的可读性。
搜索框和底部操作栏可以先试 THIN
搜索框和底部操作栏既要保留页面背景,也要确保输入文字、按钮和图标足够清楚。
THIN 会比 ULTRA_THIN 多削弱一部分背景,组件自身仍然保持轻量。搜索框和底部悬浮区域都适合从这一档开始。
我在已有项目中通常先用 THIN 测试底部操作栏。按钮数量较多,或者背景图案比较复杂时,再向 REGULAR 调整。
普通悬浮卡片可以从 REGULAR 开始
REGULAR 位于五档样式中间,也是 ImmersiveMaterial 的默认样式。开发者没有填写 style 时,系统会采用这一档。
它适合作为比较基准。搜索框可以拿它和 THIN 比较,菜单可以拿它和 THICK 比较。这样比每次都测试五档更容易缩小范围。
菜单和临时浮层可以先试 THICK
菜单可能出现在图片、列表或视频上方,开发者很难提前控制它后面的背景。
THICK 能够明显降低背景干扰,让菜单文字和选项保持稳定。可能在任意位置弹出的临时组件也可以先从这一档开始。
菜单面积较小、背景又比较简单时,REGULAR 也可能已经够用,最终仍要结合真实页面判断。
弹窗和半模态页面可以先试 ULTRA_THICK
弹窗和半模态页面占据的面积更大,内部通常包含标题、正文、表单和操作按钮。
ULTRA_THICK 会进一步弱化背景,帮助当前内容形成清楚的层级。半模态页面和大面积弹出框也属于这一档的典型场景。
内容很少的小弹窗使用这一档后可能显得偏重。遇到这种情况,可以退回 THICK 再比较一次。
把组件位置和面积加入判断以后,五档样式就形成了更清楚的起始范围。
| 组件场景 | 建议先试 | 相邻比较 |
|---|---|---|
| 顶部悬浮工具栏 | ULTRA_THIN |
背景复杂时比较 THIN |
| 搜索框 | THIN |
比较 ULTRA_THIN 与 REGULAR |
| 底部操作栏 | THIN |
内容较多时比较 REGULAR |
| 普通悬浮卡片 | REGULAR |
根据背景向两侧调整 |
| 菜单和临时浮层 | THICK |
面积较小时比较 REGULAR |
| 弹窗和半模态页面 | ULTRA_THICK |
内容较少时比较 THICK |
有了这张范围表,下一步就可以搭建一个变量足够少的页面,让五档样式在同一环境中直接对比。

三、怎样搭建一个可比较的最小页面
场景建议能够帮助开发者缩小范围,最终取值仍然需要通过运行结果判断。
为了让结果具有可比性,五张卡片必须使用相同条件。背景、尺寸、圆角或文字发生变化以后,页面差异就很难继续归因于 ImmersiveStyle。
当前示例统一使用下面这些条件:
- 五张卡片使用相同的宽度和高度。
- 五张卡片使用相同的圆角和文字层级。
- 五张卡片使用相同的三段彩色背景。
- 五个材质对象只修改
style。 - 页面使用相同的主题和沉浸光感强度。
- 截图使用相同的模拟器窗口尺寸。
ImmersiveMaterial 默认采用 REGULAR,材质赋色未设置,自动反色关闭,材质阴影开启,交互形变关闭,触点光感未设置。当前测试只覆盖 style,其余参数继续使用默认值。
这样处理以后,页面中最主要的变量就只剩材质厚度。
先创建五个材质对象
五个对象分别设置对应的 ImmersiveStyle。
private readonly ultraThinMaterial: uiMaterial.Material =
new uiMaterial.ImmersiveMaterial({
style: uiMaterial.ImmersiveStyle.ULTRA_THIN
});
private readonly thinMaterial: uiMaterial.Material =
new uiMaterial.ImmersiveMaterial({
style: uiMaterial.ImmersiveStyle.THIN
});
private readonly regularMaterial: uiMaterial.Material =
new uiMaterial.ImmersiveMaterial({
style: uiMaterial.ImmersiveStyle.REGULAR
});
private readonly thickMaterial: uiMaterial.Material =
new uiMaterial.ImmersiveMaterial({
style: uiMaterial.ImmersiveStyle.THICK
});
private readonly ultraThickMaterial: uiMaterial.Material =
new uiMaterial.ImmersiveMaterial({
style: uiMaterial.ImmersiveStyle.ULTRA_THICK
});
这一轮没有开启 interactive 和 lightEffect。按压形变与触点光感会增加新的观察变量,后续验证交互参数时再打开更合适。
再让五张卡片共用同一套结构
五个材质对象通过同一个 @Builder 显示。
@Builder
private materialCard(
title: string,
scene: string,
material: uiMaterial.Material
) {
Stack() {
this.comparisonBackground()
Column({ space: 7 }) {
Text(title)
.fontSize(18)
.fontWeight(FontWeight.Bold)
.fontColor('#17203A')
Text(scene)
.fontSize(13)
.fontColor('#596179')
}
.width('88%')
.height(96)
.borderRadius(24)
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
.systemMaterial(material)
}
.width('100%')
.height(142)
.borderRadius(24)
.clip(true)
}
五张卡片共用同一组背景和布局。后续需要调整测试条件时,只修改一个构建方法即可,也能避免卡片尺寸出现偏差。
页面完成以后,运行结果可以按照轻薄、常规和厚重三组逐步观察。
四、模拟器中的五档样式为什么看起来一样
按照最初的测试计划,我准备把五档样式分成三组观察:先比较 ULTRA_THIN 和 THIN,再把 REGULAR 作为中间参照,最后比较 THICK 和 ULTRA_THICK。
实际运行以后,页面给出的结果与预期并不一致。
五个 ImmersiveStyle 都能正常创建,五张卡片也都成功显示了沉浸材质,但它们在当前 HarmonyOS 7 模拟器中的视觉效果基本相同。背景颜色、文字透出程度、卡片通透度和整体层级都没有出现稳定、可辨认的差异。

当前示例在 HarmonyOS 7 模拟器中运行。五档材质对象都能正常创建并通过 systemMaterial 设置到组件上,说明接口调用和页面结构可以正常执行。不过,从实际截图来看,五张卡片没有呈现出清楚的厚度差异。
这个结果意味着,当前模拟器适合确认下面几项内容:
ImmersiveStyle的五个枚举值可以正常使用。ImmersiveMaterial可以成功创建材质对象。- 普通 ArkUI 组件可以通过
systemMaterial显示沉浸材质。 - 五张卡片使用了相同的测试条件。
我先后使用了纯色分区、背景文字和更高密度的测试元素,模拟器中的五档结果仍然接近。结合这次运行情况,我们更适合把官方定义与模拟器结果分开记录:
| 内容 | 当前能够确认的结论 |
|---|---|
| 五档枚举与接口调用 | 模拟器中可以正常执行 |
| 沉浸材质基础显示 | 模拟器中可以正常显示 |
| 五档视觉差异 | 当前模拟器中未观察到明显区别 |
| 具体场景选型 | 参考接口和设计指南,仍需真机验证 |
| 最终材质效果 | 以具备 HarmonyOS 7 测试权限的真机为准 |
这个结果虽然没有呈现预期中的五档变化,但它仍然有实际价值。开发者在模拟器中看到五档效果一致时,不需要立即怀疑枚举写错或材质对象创建失败。页面已经显示沉浸材质,说明基础调用链路已经接通;当前环境只是没有提供足够明确的视觉差异。
目前我的测试设备还没有相应的 HarmonyOS 7 实机测试权限,因此这一轮只能记录模拟器结果。具备开发者权限和支持设备时,建议使用同一份页面代码继续完成真机测试,并重点观察:
- 背景文字和细线的保留程度。
- 彩色区域交界处的柔化程度。
- 卡片高光、阴影和边框的变化。
- 大面积组件使用厚材质后的视觉重量。
- 强、均衡和弱三种系统设置下的差异。
看完五档对比以后,项目还需要结合具体组件做最后一轮选择。
我的习惯是先根据组件位置选出一档,然后向相邻两档各测试一次。这样既能控制工作量,也能避免第一印象直接决定最终结果。
搜索框可以比较三档
搜索框可以从 THIN 开始,然后比较:
ULTRA_THIN
THIN
REGULAR
背景比较简单时,ULTRA_THIN 可能已经足够。背景存在图片、列表文字或高对比图案时,REGULAR 的前景稳定性更值得关注。
底部操作栏需要看按钮数量
按钮数量较少时,可以先比较 ULTRA_THIN 和 THIN。
按钮、文字和状态较多时,可以继续加入 REGULAR。组件面积增大以后,过薄材质可能保留过多背景,进而影响图标和文字。
普通卡片可以把 REGULAR 当作起点
普通悬浮卡片可以先使用 REGULAR。
卡片主要用于简单操作时,可以向 THIN 调整。卡片包含较多说明文字和按钮时,可以向 THICK 调整。
菜单可以比较三档
菜单可以依次比较:
REGULAR
THICK
ULTRA_THICK
菜单背景简单、面积较小时,REGULAR 可能已经够用。菜单可能覆盖图片、视频或复杂页面时,THICK 通常更稳定。
弹窗和半模态页面需要关注整体重量
半模态页面可以从 ULTRA_THICK 开始,再与 THICK 比较。
内容较多时,超厚材质能够减少背景干扰。内容较少时,过厚材质可能让页面显得沉重,这时需要同时观察内容可读性和页面层级。
最终选择可以归纳为四步:
确认组件位置
↓
判断组件面积和信息密度
↓
选择一个起始样式
↓
与相邻样式进行同条件比较
这个过程不会一次解决所有页面,但它能够为每个组件留下清楚的选择依据。项目后续调整背景、字号或布局时,也可以继续沿用同样的测试方式。
总结
把五档材质放进同一个页面以后,我对 ImmersiveStyle 的理解也从枚举名称变成了更具体的页面判断。
ULTRA_THIN 会保留更多背景信息,适合顶部悬浮区域。THIN 在通透感和前景稳定性之间更容易取得平衡,搜索框和底部操作栏可以先从这一档开始。
REGULAR 是默认样式,也适合作为比较基准。THICK 能够减少复杂背景对内容的干扰,菜单和临时浮层可以优先测试。ULTRA_THICK 会进一步强化前后层级,大面积弹窗和半模态页面更容易从中受益。
对于已有项目,我更建议先从一个组件开始。搜索框比较三档,菜单比较三档,弹窗再比较两档。测试范围足够小,团队更容易看清差异,也能为后续调整留下依据。
模拟器暂时没有呈现出明显的五档差异,项目仍然可以根据官方定义和组件场景缩小选择范围。真正确定最终样式时,还需要把相邻档位放到支持相关能力的真机上继续比较。
这次运行让我确认了五档 ImmersiveStyle 的接口调用方式,也让我看到了模拟器验证的边界。五个材质对象都能正常显示,但当前模拟器没有呈现出稳定的视觉差异。因此,本文中的场景建议主要来自接口定义与设计指南,最终样式仍要通过真机运行结果确定。
完整代码
Main.ets
/**
* HarmonyOS 7 沉浸光感深度实战 03
*
* 验证环境:
* HarmonyOS SDK API 26
* HarmonyOS 7 模拟器
*/
import { uiMaterial } from '@kit.ArkUI';
@Entry
@Component
struct Main {
@State private materialStateText: string =
'当前应用尚未读取状态';
@State private stateColor: ResourceColor =
'#68708A';
@State private stateDescription: string =
'页面尚未读取应用级材质状态';
/**
* 五个材质对象只设置 style。
* 其他参数继续使用 ImmersiveMaterial 的默认值。
*/
private readonly ultraThinMaterial: uiMaterial.Material =
new uiMaterial.ImmersiveMaterial({
style: uiMaterial.ImmersiveStyle.ULTRA_THIN
});
private readonly thinMaterial: uiMaterial.Material =
new uiMaterial.ImmersiveMaterial({
style: uiMaterial.ImmersiveStyle.THIN
});
private readonly regularMaterial: uiMaterial.Material =
new uiMaterial.ImmersiveMaterial({
style: uiMaterial.ImmersiveStyle.REGULAR
});
private readonly thickMaterial: uiMaterial.Material =
new uiMaterial.ImmersiveMaterial({
style: uiMaterial.ImmersiveStyle.THICK
});
private readonly ultraThickMaterial: uiMaterial.Material =
new uiMaterial.ImmersiveMaterial({
style: uiMaterial.ImmersiveStyle.ULTRA_THICK
});
aboutToAppear(): void {
this.loadMaterialState();
}
/**
* 读取当前应用的材质状态。
* DISABLE 状态会关闭页面中的沉浸式系统材质。
*/
private loadMaterialState(): void {
const info: uiMaterial.MaterialInfo =
uiMaterial.getMaterialInfo();
this.materialStateText =
this.getMaterialStateName(info.state);
this.stateColor =
this.getMaterialStateColor(info.state);
this.stateDescription =
this.getMaterialStateDescription(info.state);
}
private getMaterialStateName(
state: uiMaterial.MaterialState
): string {
switch (state) {
case uiMaterial.MaterialState.DEFAULT:
return 'DEFAULT';
case uiMaterial.MaterialState.ENABLE:
return 'ENABLE';
case uiMaterial.MaterialState.DISABLE:
return 'DISABLE';
default:
return `未知状态 ${state}`;
}
}
private getMaterialStateColor(
state: uiMaterial.MaterialState
): ResourceColor {
switch (state) {
case uiMaterial.MaterialState.DEFAULT:
return '#5065E8';
case uiMaterial.MaterialState.ENABLE:
return '#1A8F5D';
case uiMaterial.MaterialState.DISABLE:
return '#C85A3A';
default:
return '#68708A';
}
}
private getMaterialStateDescription(
state: uiMaterial.MaterialState
): string {
switch (state) {
case uiMaterial.MaterialState.DEFAULT:
return '当前状态允许普通组件主动设置沉浸材质。';
case uiMaterial.MaterialState.ENABLE:
return '当前状态允许页面比较五档沉浸材质。';
case uiMaterial.MaterialState.DISABLE:
return '当前状态会关闭页面中的全部沉浸材质。';
default:
return '当前状态没有对应说明。';
}
}
@Builder
private sectionTitle(
title: string,
description: string
) {
Column({ space: 4 }) {
Text(title)
.fontSize(22)
.fontWeight(FontWeight.Bold)
.fontColor('#11182C')
.width('100%')
Text(description)
.fontSize(14)
.fontColor('#68708A')
.lineHeight(21)
.width('100%')
}
.alignItems(HorizontalAlign.Start)
.width('100%')
}
/**
* 三段背景同时保留颜色、文字和分界线,
* 方便观察不同样式对背景细节的处理。
*/
@Builder
private comparisonBackground() {
Row() {
Column({ space: 4 }) {
Text('01')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.fontColor('#DDE3FF')
Text('BLUE')
.fontSize(11)
.fontColor('#DDE3FF')
}
.width('34%')
.height('100%')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
.backgroundColor('#4B62FF')
Column({ space: 4 }) {
Text('02')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.fontColor('#E5F5FF')
Text('LIGHT')
.fontSize(11)
.fontColor('#E5F5FF')
}
.width('32%')
.height('100%')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
.backgroundColor('#59B7FF')
Column({ space: 4 }) {
Text('03')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.fontColor('#F0E5FF')
Text('PURPLE')
.fontSize(11)
.fontColor('#F0E5FF')
}
.layoutWeight(1)
.height('100%')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
.backgroundColor('#A266FF')
}
.width('100%')
.height('100%')
}
/**
* 所有卡片共用相同的尺寸、圆角、背景和文字结构。
*/
@Builder
private materialCard(
title: string,
scene: string,
material: uiMaterial.Material
) {
Stack() {
this.comparisonBackground()
Column({ space: 7 }) {
Text(title)
.fontSize(18)
.fontWeight(FontWeight.Bold)
.fontColor('#17203A')
Text(scene)
.fontSize(13)
.fontColor('#596179')
}
.width('88%')
.height(96)
.borderRadius(24)
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
.systemMaterial(material)
}
.width('100%')
.height(142)
.borderRadius(24)
.clip(true)
}
@Builder
private stateCard() {
Column({ space: 8 }) {
Row({ space: 12 }) {
Text('MaterialState')
.width('38%')
.fontSize(14)
.fontColor('#68708A')
Text(this.materialStateText)
.layoutWeight(1)
.fontSize(14)
.fontWeight(FontWeight.Medium)
.fontColor(this.stateColor)
.textAlign(TextAlign.End)
.maxLines(2)
}
.width('100%')
.alignItems(VerticalAlign.Center)
Divider()
.color('#E8EBF2')
Text(this.stateDescription)
.fontSize(13)
.fontColor('#68708A')
.lineHeight(20)
.width('100%')
}
.width('100%')
.padding(16)
.backgroundColor(Color.White)
.borderRadius(20)
}
build() {
Scroll() {
Column({ space: 18 }) {
Column({ space: 6 }) {
Text('HarmonyOS 7 沉浸光感')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.fontColor('#11182C')
.width('100%')
Text('五档 ImmersiveStyle 对比')
.fontSize(16)
.fontColor('#68708A')
.width('100%')
}
.alignItems(HorizontalAlign.Start)
.width('100%')
this.sectionTitle(
'当前应用状态',
'DEFAULT 和 ENABLE 可以比较样式,DISABLE 会关闭全部材质。'
)
this.stateCard()
this.sectionTitle(
'统一条件对比',
'五张卡片只修改 ImmersiveStyle,其余参数保持默认。'
)
this.materialCard(
'ULTRA_THIN',
'顶部悬浮区域与轻量工具栏',
this.ultraThinMaterial
)
this.materialCard(
'THIN',
'搜索框与底部操作栏',
this.thinMaterial
)
this.materialCard(
'REGULAR',
'普通卡片与通用场景',
this.regularMaterial
)
this.materialCard(
'THICK',
'菜单与临时浮层',
this.thickMaterial
)
this.materialCard(
'ULTRA_THICK',
'弹窗与半模态页面',
this.ultraThickMaterial
)
Text(
'请保持系统主题、沉浸光感强度和模拟器窗口尺寸一致。'
)
.fontSize(13)
.fontColor('#747C92')
.lineHeight(20)
.padding({
top: 4,
bottom: 24
})
.width('100%')
}
.width('100%')
.padding({
left: 20,
right: 20,
top: 24,
bottom: 24
})
}
.width('100%')
.height('100%')
.backgroundColor('#F4F6FB')
}
}
更多推荐



所有评论(0)