HarmonyOS 鸿蒙Next实现组件遮罩(组件添加蒙层)
HarmonyOS 鸿蒙Next实现组件遮罩(组件添加蒙层) 在HarmonyOS应用开发中,在进行 UI 绘制的过程中,会有对某个组件绘制遮罩(蒙层)的需求。如果是使用 html 开发,可以在父级里面添加一个子级添加上 position:absolute,去实现一个填满父级的遮罩层,如下:
<div style="position: relative;background: #f2f2f2;width: 500px;">
<div style="background: #000;width: 100%;height: 100%;position: absolute;opacity: 0.4;"></div>
<div>你好</div>
</div>
但是在鸿蒙里面使用同样的的想法进行编码发现不能实现,使用Stack,子级的高度不能自动填满,需要自己设定固定高度才可以,但是一般渲染内容是动态的,高度是不固定的,如果写死一个固定高度就达不到 UI 的验收标准。那要如何实现?查阅文档发现,可以使用mask 属性实现。
Column(){
Text('你好')
}.mask(new ProgressMask(0, 1, '#80ffffff')
更多关于HarmonyOS 鸿蒙Next实现组件遮罩(组件添加蒙层)的实战教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,实现组件遮罩(蒙层)主要有两种方式:
-
使用通用属性:在组件上设置
opacity属性来控制透明度,或使用background属性设置半透明背景色。 -
使用
overlay属性:这是更直接的方法。在需要被遮罩的组件上添加overlay修饰器,其参数是一个自定义的遮罩组件(通常是一个设置了背景色的Blank或Column组件)。
例如,为一个Button添加红色半透明遮罩:
Button('按钮')
.overlay(
Blank()
.width('100%')
.height('100%')
.backgroundColor(Color.Red)
.opacity(0.5)
)
在HarmonyOS Next中,实现组件遮罩(蒙层)主要有两种推荐方案,可以很好地解决动态内容高度不固定的问题。
方案一:使用Stack布局配合绝对定位
这是最接近Web开发思维的方式。关键在于使用Stack布局,并为遮罩层组件设置.position({ x: 0, y: 0 })和.width('100%').height('100%'),使其完全覆盖父容器。
@Entry
@Component
struct MaskExample {
build() {
Stack({ alignContent: Alignment.TopStart }) {
// 这是你的主要内容
Column() {
Text('动态内容区域')
.fontSize(20)
.padding(20)
// 这里可以有任意动态内容,高度会自动撑开
}
.border({ width: 1, color: Color.Gray })
.padding(20)
// 这是遮罩层 - 关键代码
Column() {
// 遮罩层内容,可以是半透明背景、加载动画等
}
.position({ x: 0, y: 0 })
.width('100%')
.height('100%')
.backgroundColor('#80000000') // 50%透明黑色
.opacity(0.5) // 也可以使用opacity控制透明度
}
.width('100%')
.height('100%')
.backgroundColor(Color.White)
}
}
核心要点:
Stack布局默认允许子组件堆叠.position({ x: 0, y: 0 })将遮罩定位到左上角.width('100%').height('100%')让遮罩充满整个Stack容器- 遮罩层必须放在主要内容之后,这样才会显示在上层
方案二:使用mask属性(官方推荐)
这是HarmonyOS特有的方式,通过给组件添加mask来实现遮罩效果:
@Entry
@Component
struct MaskExample2 {
build() {
Column() {
Text('需要遮罩的内容')
.fontSize(30)
.padding(40)
.backgroundColor(Color.Blue)
.mask(
new Rect()
.width('100%')
.height('100%')
.fillOpacity(0.5)
.fill(Color.Black)
)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
或者使用更灵活的Shape:
.mask(
new Shape()
.width('100%')
.height('100%')
.fill(Color.Black)
.opacity(0.5)
)
两种方案对比:
-
Stack方案:
- 优点:更灵活,可以在遮罩层上添加其他交互元素(如关闭按钮、提示文字)
- 缺点:需要手动管理层级
-
mask方案:
- 优点:性能更好,代码更简洁,是官方推荐做法
- 缺点:遮罩层不能包含交互元素,只能是纯视觉遮罩
实际应用示例(带交互的遮罩):
@Entry
@Component
struct InteractiveMask {
@State showMask: boolean = false
build() {
Stack({ alignContent: Alignment.TopStart }) {
// 主要内容
Column() {
Button('显示遮罩')
.onClick(() => {
this.showMask = !this.showMask
})
Text('一些动态内容...')
.margin({ top: 20 })
}
.padding(20)
// 条件渲染的遮罩层
if (this.showMask) {
Column() {
Text('加载中...')
.fontColor(Color.White)
.fontSize(16)
Button('关闭')
.margin({ top: 20 })
.onClick(() => {
this.showMask = false
})
}
.position({ x: 0, y: 0 })
.width('100%')
.height('100%')
.backgroundColor('#80000000')
.justifyContent(FlexAlign.Center)
}
}
.width('100%')
.height('100%')
}
}
对于大多数简单的遮罩需求,推荐使用mask属性方案,代码更简洁性能更好。如果需要复杂的交互遮罩(如弹窗、引导层),则使用Stack布局方案更合适。两种方案都能完美适应动态内容的高度变化。

