HarmonyOS鸿蒙Next中如何实现毛玻璃效果的卡片组件?

HarmonyOS鸿蒙Next中如何实现毛玻璃效果的卡片组件? 我想创建一个具有现代化毛玻璃效果的卡片组件,支持标题、副标题、图标和自定义内容插槽,如何实现?

3 回复

实现思路:

  1. 定义组件属性,使用 @Prop 接收外部参数,@BuilderParam 定义内容插槽:
@Component
export struct GlassCard {
  [@Prop](/user/Prop) title: string = '';
  [@Prop](/user/Prop) subtitle: string = '';
  [@BuilderParam](/user/BuilderParam) content?: () => void;
}
  1. 使用 @State 管理按压状态,实现按压缩放动画效果:
[@State](/user/State) isPressed: boolean = false;

.scale({ x: this.isPressed ? 0.98 : 1, y: this.isPressed ? 0.98 : 1 })
.animation({ duration: 150, curve: Curve.EaseOut })
  1. 使用 shadow 和 backgroundColor 实现毛玻璃视觉效果:
.backgroundColor('#FFFFFF')
.borderRadius(16)
.shadow({ radius: 12, color: 'rgba(0,0,0,0.08)', offsetX: 0, offsetY: 4 })
  1. 完整示例代码:
@Component
export struct GlassCard {
  [@Prop](/user/Prop) title: string = '';
  [@Prop](/user/Prop) subtitle: string = '';
  [@Prop](/user/Prop) icon: string = '';
  [@Prop](/user/Prop) showArrow: boolean = false;
  [@BuilderParam](/user/BuilderParam) content?: () => void;
  onTap?: () => void;
  [@State](/user/State) isPressed: boolean = false;

  build() {
    Column() {
      if (this.title || this.icon) {
        Row({ space: 12 }) {
          if (this.icon) {
            Text(this.icon).fontSize(24)
          }
          Column({ space: 2 }) {
            if (this.title) {
              Text(this.title).fontSize(16).fontWeight(FontWeight.Bold).fontColor('#333333')
            }
            if (this.subtitle) {
              Text(this.subtitle).fontSize(12).fontColor('#999999')
            }
          }
          .alignItems(HorizontalAlign.Start)
          .layoutWeight(1)
          if (this.showArrow) {
            Text('>').fontSize(16).fontColor('#CCCCCC')
          }
        }
        .width('100%')
      }
      if (this.content) {
        Column() { this.content() }.width('100%').margin({ top: this.title ? 12 : 0 })
      }
    }
    .width('100%')
    .padding(16)
    .backgroundColor('#FFFFFF')
    .borderRadius(16)
    .shadow({ radius: 12, color: 'rgba(0,0,0,0.08)', offsetX: 0, offsetY: 4 })
    .scale({ x: this.isPressed ? 0.98 : 1, y: this.isPressed ? 0.98 : 1 })
    .animation({ duration: 150, curve: Curve.EaseOut })
    .onTouch((event: TouchEvent) => {
      if (this.onTap) {
        if (event.type === TouchType.Down) this.isPressed = true;
        else if (event.type === TouchType.Up || event.type === TouchType.Cancel) this.isPressed = false;
      }
    })
    .onClick(() => this.onTap?.())
  }
}

更多关于HarmonyOS鸿蒙Next中如何实现毛玻璃效果的卡片组件?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


鸿蒙Next中实现毛玻璃效果卡片组件

实现毛玻璃效果主要通过ArkUI的@ohos.effectKit模块的Filter能力。使用backdropBlur滤镜,结合Componentblur属性或GraphicsContext进行绘制。

核心步骤

  1. 创建Filter对象:从@ohos.effectKit模块导入并创建滤镜对象。
  2. 设置模糊半径:为创建的滤镜对象配置模糊半径参数,控制毛玻璃的模糊程度。
  3. 应用到组件:将配置好的滤镜效果应用到卡片组件的背景或指定的绘制区域。

示例代码片段

以下代码展示了如何将模糊效果与卡片UI结合:

// 示例代码:创建并应用毛玻璃滤镜
import effectKit from '@ohos.effectKit';

// 创建Filter对象
let filter: effectKit.Filter = effectKit.createEffect(effectKit.EffectType.BACKDROP_BLUR);

// 设置模糊半径
filter.setBackdropBlur(10.0); // 数值越大,越模糊

// 将滤镜应用到某个组件的背景或GraphicsContext
// 此处为示例逻辑,具体应用方式需结合组件API
// component.backgroundFilter = filter;

关键点:实际应用中,需要根据具体的组件类型和UI结构,选择通过blur属性或GraphicsContext的绘制接口来施加滤镜效果。

在HarmonyOS Next中,可以通过@ohos.graphics.displayEffect模块的Filter能力,结合组件背景模糊与半透明遮罩,实现毛玻璃效果卡片。以下是核心实现步骤:

  1. 创建模糊背景层:使用Stack组件,底层放置需要模糊的背景(如动态壁纸或图片),通过backgroundFilter属性应用高斯模糊。

    // 示例:背景模糊层
    Stack() {
      Image($r('app.media.background'))
        .backgroundFilter(Filter.blur(10)) // 应用模糊滤镜
      
      // 卡片内容层
      Column() {
        // 卡片内容:标题、图标等
      }
      .glassCardStyle() // 自定义卡片样式
    }
    
  2. 定义卡片样式:通过[@Styles](/user/Styles)装饰器封装毛玻璃样式,包含半透明背景与边缘圆角。

    [@Styles](/user/Styles) function glassCardStyle() {
      .width('90%')
      .padding(20)
      .backgroundColor(Color.White)
      .opacity(0.6) // 调整透明度增强毛玻璃质感
      .borderRadius(16)
      .backdropFilter(Filter.blur(5)) // 叠加前景模糊增强层次
    }
    
  3. 支持内容插槽:使用@BuilderParam装饰器接收自定义内容,实现灵活的内容扩展。

    [@Component](/user/Component)
    struct GlassCard {
      @BuilderParam content: () => void
      
      build() {
        Column() {
          this.content()
        }
        .glassCardStyle()
      }
    }
    
  4. 动态效果优化:结合@State变量与animateTo方法,可实现卡片悬停或点击时的模糊度动态变化,提升交互体验。

注意事项:

  • 模糊半径建议控制在5-15之间,避免性能过度消耗。
  • 可通过opacitybackgroundColor调整卡片透光性,适配不同背景场景。
  • 使用backdropFilter时需注意系统兼容性(API 12+)。

此方案通过系统级滤镜实现高性能模糊渲染,同时保持卡片内容的清晰可读性。

回到顶部