一、前言

在鸿蒙 ArkUI 项目开发里,很多页面视觉效果,开发者第一反应都是靠多层组件嵌套叠加实现。想要渐变背景就外层套容器 + 内层色块;卡片阴影单独写一层透明占位组件;图片柔光、暗角效果,直接用多张图片叠加或者引入第三方处理库。

这种写法短期能快速做出视觉效果,但项目迭代久了问题会集中暴露:页面 DOM 层级堆叠严重,引发 GPU 过度绘制,列表滑动时频繁掉帧;各处样式写死在页面内,色值、模糊参数分散,UI 改版需要逐个页面修改,很难维持全项目视觉统一。

ArkUI 内置的渐变、阴影、滤镜能力,本身就可以在单个组件上完成复杂视觉渲染,减少多余嵌套。本文基于最新 API,讲解这三类属性的高阶写法,用更少组件实现统一 UI 规范,附带可直接运行的代码示例。

二、渐变:不止纯色过渡,多色分段 + 角度定位

linearGradient 线性渐变、radialGradient 径向渐变是开发最常用的两种渐变。很多人只写两色渐变,实际上多色节点、偏移位置、角度控制,可以直接实现分割底色、渐变蒙版,省去额外叠加容器。

@Entry
@Component
struct GradientDemo {
  build() {
    Column() {
      // 线性渐变,多色分段,卡片标题背景
      Text("线性渐变卡片")
        .width("90%")
        .height(80)
        .fontSize(18)
        .fontColor("#fff")
        .padding(16)
        .linearGradient({
          direction: GradientDirection.EndToStart,
          colors: [
            [0x0066ff, 0.0],
            [0x3399ff, 0.6],
            [0x66bbff, 1.0]
          ]
        })
        .borderRadius(12)
        .margin({bottom:20})

      // 径向渐变,圆形渐变蒙版
      Text("径向渐变效果")
        .width("90%")
        .height(160)
        .fontSize(18)
        .fontColor("#fff")
        .padding(16)
        .radialGradient({
          centerX: "50%",
          centerY: "50%",
          radius: "80%",
          colors: [
            [0xff7722, 0.0],
            [0xffbb66, 1.0]
          ]
        })
        .borderRadius(12)
    }
    .padding(20)
    .width("100%")
  }
}

colors 数组第二个参数是位置占比,取值 0~1。利用这个特性,还能实现硬分割的色块效果,不再需要两个 Row 并排叠加。

三、阴影高阶:内外阴影、多层阴影,替代悬浮遮罩组件

shadow 属性日常大多用来做卡片底部投影。很多人不知道,支持多组阴影同时声明,也可以配合 offset 调整方向,做出内阴影凹陷效果,不用额外增加一层 View 模拟凹陷。

@Entry
@Component
struct ShadowDemo {
  build() {
    Column() {
      // 多层外阴影,模拟悬浮层次感
      Text("多层悬浮卡片")
        .width("90%")
        .height(100)
        .fontSize(18)
        .padding(16)
        .backgroundColor("#ffffff")
        .borderRadius(16)
        .shadow([
          { radius: 12, color: "#10000000", offsetX: 0, offsetY: 4 },
          { radius: 24, color: "#08000000", offsetX: 0, offsetY: 8 }
        ])
        .margin({bottom:20})

      // 内阴影,凹陷面板效果
      Text("内阴影凹陷面板")
        .width("90%")
        .height(100)
        .fontSize(18)
        .padding(16)
        .backgroundColor("#f5f7fa")
        .borderRadius(16)
        .shadow({
          radius: 6,
          color: "#20000000",
          offsetX: 0,
          offsetY: 2,
          isInner: true
        })
    }
    .padding(20)
    .width("100%")
  }
}

isInner 开启后阴影向内绘制。多层阴影叠加可以营造远近层次感,原本需要嵌套两层容器才能实现的悬浮效果,现在单组件完成。

四、滤镜 filter:模糊、色相、亮度调整,图片美化免叠加

filter 滤镜可以作用在图片、容器上,支持高斯模糊、亮度、对比度、饱和度等组合调整。做图片暗角、图片变暗蒙版、背景毛玻璃,不需要叠加半透明组件,直接给组件设置 filter。

@Entry
@Component
struct FilterDemo {
  build() {
    Column() {
      Image($r("sys.media.ohos_ic_public_cover"))
        .width("90%")
        .height(180)
        .objectFit(ImageFit.Cover)
        .borderRadius(12)
        .filter(
          filterBrightness(0.8)
            .combine(filterSaturate(1.2))
            .combine(filterBlur(2))
        )
        .margin({bottom:20})

      Text("毛玻璃文字面板")
        .width("90%")
        .height(80)
        .fontSize(18)
        .fontColor("#fff")
        .textAlign(TextAlign.Center)
        .borderRadius(12)
        .backdropBlur(8)
        .backgroundColor("#20ffffff")
    }
    .padding(20)
    .width("100%")
  }
}

filter 支持链式 combine 组合多种滤镜参数。backdropBlur 是背景模糊,区别于 filterBlur,前者模糊组件后方画面,适合弹窗、卡片毛玻璃场景;后者模糊组件自身内容。

五、统一 UI:封装全局样式,消除冗余代码

项目中,卡片、渐变标题、悬浮面板样式往往多处复用。我们可以抽离 @Builder,统一管理渐变、阴影、滤镜参数,全项目复用一套视觉标准。

@Builder
function CardNormal() {
  Column()
    .width("100%")
    .backgroundColor("#fff")
    .borderRadius(16)
    .shadow([
      { radius: 12, color: "#10000000", offsetX: 0, offsetY: 4 },
      { radius: 24, color: "#08000000", offsetX: 0, offsetY: 8 }
    ])
}

@Builder
function GradientTitle() {
  Text()
    .width("100%")
    .height(72)
    .linearGradient({
      direction: GradientDirection.EndToStart,
      colors: [
        [0x0066ff, 0.0],
        [0x3399ff, 1.0]
      ]
    })
    .borderRadius({topLeft:12, topRight:12})
}

@Entry
@Component
struct UiBuildDemo {
  build() {
    Column() {
      GradientTitle()
      CardNormal() {
        Text("业务卡片内容").fontSize(16).padding(16)
      }
    }
    .width("90%")
    .padding(20)
  }
}

所有视觉参数集中维护,后续 UI 改版,只修改这一处 Builder,页面全部同步更新,不用逐个页面查找修改。

六、小结

渐变、阴影、滤镜这几个属性不只是锦上添花的美化能力,更是精简组件结构、统一项目 UI 规范的工具。很多多层嵌套实现的视觉效果,都可以合并到单个组件上完成,降低页面层级,减少过度绘制。

在实际开发中,把通用视觉样式抽离为 Builder,统一管理色值、模糊半径、阴影参数。后续新增页面直接复用,既能保持视觉风格统一,也减少大量重复冗余布局代码。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐