干货分享:一文掌握HarmonyOS Next自定义高斯模糊弹窗 原创 精华

全栈若城
发布于 2025-9-5 09:35
浏览
1收藏

@toc

前言

大家好,我是若城。本系列专注于帮助开发者快速实现HarmonyOS Next应用中的常用功能,提供即拿即用的代码示例。

前几篇文章主要聚焦于应用功能层面的实现,本篇我们将转换视角,深入探讨UI交互设计的精髓——自定义高斯模糊弹窗的完整实现方案。话不多说开始上课~~~

效果演示

本文将实现一个功能丰富的自定义弹窗组件,具备以下特性:

  • 高斯模糊背景:营造现代化毛玻璃视觉效果
  • 内容完全自定义:支持任意内容和布局格式
  • 优雅的交互动画:平滑的显示/隐藏过渡效果
  • 精美的关闭按钮:一键关闭,用户体验友好
  • 广泛适用性:适合各类内容展示场景

干货分享:一文掌握HarmonyOS Next自定义高斯模糊弹窗-鸿蒙开发者社区

完整实现方案

1. 数据结构定义

定义数据类型

interface Poem {
    _id: string;
    date: string;
    author: string;
    content: string;
    from: string;
    like: number;
    pic_url: ResourceStr;
    share: number;
    thumb: ResourceStr;
}


定义相关数据


   @State wallpaperData: Poem =   {
        "_id": "c4ee5e1ec8bc480b8df05428",
        "date": "20250814",
        "author": "宝树",
        "content": "科幻文学中的时间旅行题材,能够让我们思考时间的本质和人生的意义,它充满了奇幻色彩和哲学思辨。时间旅行是科幻文学中一个经典的主题。",
        "from": "科幻作家",
        "like": 220,
        "share": 351,
        "pic_url": $r('app.media.20250818'),
        "thumb": $r('app.media.20250818')
    }

定义弹窗状态变量 以及 切换函数

  @State showDialog: boolean = false;
  
 handleShow=()=>{
        this.showDialog = !this.showDialog
    }

高斯弹窗的核心代码


            if (this.showDialog) {
                Column() {
                    // 名言内容卡片
                    Column() {
                        // 引号装饰
                        Text('"')
                            .fontSize(48)
                            .fontColor('#FFFFFF60')
                            .fontWeight(FontWeight.Bold)
                            .alignSelf(ItemAlign.Start)
                            .margin({ bottom: -10 })

                        Text(this.wallpaperData.content)
                            .fontSize(20)
                            .fontColor(Color.White)
                            .lineHeight(32)
                            .textAlign(TextAlign.Start)
                            .fontWeight(FontWeight.Medium)
                            .margin({ bottom: 24 })

                        // 作者信息
                        Row() {
                            Column() {
                                Text(`—— ${this.wallpaperData.author}`)
                                    .fontSize(18)
                                    .fontColor('#FFFFFFCC')
                                    .fontWeight(FontWeight.Medium)
                                Text(this.wallpaperData.from)
                                    .fontSize(14)
                                    .fontColor('#FFFFFF80')
                                    .margin({ top: 4 })
                            }
                            .alignItems(HorizontalAlign.Start)
                            .layoutWeight(1)


                        }
                        .width('100%')
                        .alignItems(VerticalAlign.Bottom)
                    }
                    .width('100%')
                    .padding(32)
                    .backgroundColor('#1A1A1AE6')
                    .borderRadius(24)
                    .backdropBlur(30)
                    .border({ width: 1, color: '#FFFFFF30' })
                    .shadow({
                        radius: 20,
                        color: '#00000060',
                        offsetX: 0,
                        offsetY: 8
                    })

                    // 关闭按钮
                    Button() {
                        Text('×')
                            .fontSize(24)
                            .fontColor('#FFFFFF')
                            .fontWeight(FontWeight.Bold)
                    }
                    .width(40)
                    .height(40)
                    .backgroundColor('#FF453A60')
                    .borderRadius(20)
                    .backdropBlur(20)
                    .border({ width: 1, color: '#FF453A80' })
                    .shadow({
                        radius: 6,
                        color: '#FF453A30',
                        offsetX: 0,
                        offsetY: 2
                    })
                    .margin({ top: 16 })
                    .onClick(() => {
this.handleShow()


                    })
                }
                .width('90%')
                .justifyContent(FlexAlign.Center)
                .position({ x: '50%', y: '50%' })
                .translate({ x: '-50%', y: '-50%' })
                .transition({
                    type: TransitionType.All,
                    opacity: this.showDialog ? 1 : 0,
                    scale: { x: this.showDialog ? 1 : 0.8, y: this.showDialog ? 1 : 0.8 }
                })
            }

2. 核心技术解析

以上就是弹窗组件的完整实现代码。接下来,我们深入分析弹窗实现的三大核心技术要点:

精准定位技术

弹窗采用绝对定位配合 translate 实现完美居中显示:

 .position({ x: '50%', y: '50%' })
 .translate({ x: '-50%', y: '-50%' })
  .transition({
                    type: TransitionType.All,
                    opacity: this.showDialog ? 1 : 0,
                    scale: { x: this.showDialog ? 1 : 0.8, y: this.showDialog ? 1 : 0.8 }
                })

高斯模糊效果

高斯模糊的毛玻璃效果通过以下样式属性组合实现:

 .backgroundColor('#1A1A1AE6')
                    .borderRadius(24)
                    .backdropBlur(30)
                    .border({ width: 1, color: '#FFFFFF30' })
                    .shadow({
                        radius: 20,
                        color: '#00000060',
                        offsetX: 0,
                        offsetY: 8
                    })

各属性详细说明:

  • backgroundColor: 设置半透明深灰色背景(#1A1A1AE6),营造沉浸感
  • borderRadius: 设置24vp圆角半径,打造现代化外观
  • backdropBlur: 30vp背景模糊处理,创建经典毛玻璃效果,让背景内容模糊显示,增强视觉层次感
  • shadow: 在卡片下方创建柔和阴影,模拟悬浮效果,增强立体感

视觉设计理念

这些样式属性的巧妙组合,创造出了现代化的毛玻璃风格弹窗:

设计元素 实现效果 用户体验
半透明背景 + 背景模糊 毛玻璃质感 视觉层次丰富
圆角 + 微妙边框 现代化外观 界面更加柔和
阴影效果 立体悬浮感 增强空间感知
适当内边距 舒适布局 内容阅读友好

3. 使用方法

在页面中添加触发按钮,通过点击事件调用 handleShow() 函数,即可实现弹窗的显示与隐藏切换。

总结与展望

这个弹窗组件具有高度的可复用性和可定制性,开发者可以根据实际需求调整样式参数和内容结构,快速集成到自己的项目中。这也是我写这个组件的原因,希望对大家有所帮助。好了下课~~~~


技术交流:如果您在实现过程中遇到问题,欢迎在评论区讨论交流!

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
1
收藏 1
回复
举报
回复
    相关推荐