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

3 回复

学习了

更多关于HarmonyOS 鸿蒙Next实现组件遮罩(组件添加蒙层)的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,实现组件遮罩(蒙层)主要有两种方式:

  1. 使用通用属性:在组件上设置opacity属性来控制透明度,或使用background属性设置半透明背景色。

  2. 使用overlay属性:这是更直接的方法。在需要被遮罩的组件上添加overlay修饰器,其参数是一个自定义的遮罩组件(通常是一个设置了背景色的BlankColumn组件)。

例如,为一个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)
)

两种方案对比:

  1. Stack方案

    • 优点:更灵活,可以在遮罩层上添加其他交互元素(如关闭按钮、提示文字)
    • 缺点:需要手动管理层级
  2. 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布局方案更合适。两种方案都能完美适应动态内容的高度变化。

回到顶部