
回复
@toc
大家好,我是若城。本系列专注于帮助开发者快速实现HarmonyOS Next应用中的常用功能,提供即拿即用的代码示例。
前几篇文章主要聚焦于应用功能层面的实现,本篇我们将转换视角,深入探讨UI交互设计的精髓——自定义高斯模糊弹窗的完整实现方案。话不多说开始上课~~~
本文将实现一个功能丰富的自定义弹窗组件,具备以下特性:
定义数据类型
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 }
})
}
以上就是弹窗组件的完整实现代码。接下来,我们深入分析弹窗实现的三大核心技术要点:
弹窗采用绝对定位配合 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
})
各属性详细说明:
#1A1A1AE6
),营造沉浸感这些样式属性的巧妙组合,创造出了现代化的毛玻璃风格弹窗:
设计元素 | 实现效果 | 用户体验 |
---|---|---|
半透明背景 + 背景模糊 | 毛玻璃质感 | 视觉层次丰富 |
圆角 + 微妙边框 | 现代化外观 | 界面更加柔和 |
阴影效果 | 立体悬浮感 | 增强空间感知 |
适当内边距 | 舒适布局 | 内容阅读友好 |
在页面中添加触发按钮,通过点击事件调用 handleShow()
函数,即可实现弹窗的显示与隐藏切换。
这个弹窗组件具有高度的可复用性和可定制性,开发者可以根据实际需求调整样式参数和内容结构,快速集成到自己的项目中。这也是我写这个组件的原因,希望对大家有所帮助。好了下课~~~~
技术交流:如果您在实现过程中遇到问题,欢迎在评论区讨论交流!