本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
一、弹出框的类型
1. 模态与非模态
-
默认模态:有蒙层,不可与蒙层下方控件交互(点击/手势不透传)。
-
非模态:可通过设置
isModal: false实现,允许弹出框与页面同时交互。
2. 页面级与非页面级
-
默认非页面级:路由跳转时不会自动关闭,需手动调用
close()。 -
页面级弹窗:可使用组件导航子页面或页面级弹出框实现。
二、生命周期
从 API Version 19 开始,自定义弹出框提供以下生命周期回调:
| 名称 | 类型 | 说明 |
|---|---|---|
onWillAppear | Callback<void> | 显示动效前触发 |
onDidAppear | Callback<void> | 弹出后触发 |
onWillDisappear | Callback<void> | 退出动效前触发 |
onDidDisappear | Callback<void> | 消失后触发 |
三、创建自定义弹出框
1. 使用 @CustomDialog 装饰器定义弹出框内容
@CustomDialog
struct CustomDialogExample {
controller?: CustomDialogController
build() {
Column() {
Text('内容。。。').fontSize(20)
}
}
}
2. 在组件中创建控制器并绑定
@Entry
@Component
struct CustomDialogUser {
dialogController: CustomDialogController = new CustomDialogController({
builder: CustomDialogExample()
})
build() {
Column() {
Button('click open')
.onClick(() => {
this.dialogController.open()
})
}
}
}
四、弹出框的交互
1. 添加按钮与回调函数
@CustomDialog
struct CustomDialogExample {
cancel: () => void
confirm: () => void
controller?: CustomDialogController
build() {
Column() {
Text('内容。。。').margin({ top: 10, bottom: 10 })
Flex({ justifyContent: FlexAlign.SpaceAround }) {
Button('cancel')
.onClick(() => {
this.controller?.close()
this.cancel?.()
})
Button('confirm')
.onClick(() => {
this.controller?.close()
this.confirm?.()
})
}
}
}
}
2. 在父组件中传递回调
dialogController: CustomDialogController = new CustomDialogController({
builder: CustomDialogExample({
cancel: () => { this.onCancel() },
confirm: () => { this.onAccept() }
})
})
五、动画控制
可通过 openAnimation 配置出现动画:
new CustomDialogController({
builder: CustomDialogExample(),
openAnimation: {
duration: 1200,
curve: Curve.Friction,
delay: 500,
playMode: PlayMode.Alternate,
onFinish: () => { console.info('finish') }
}
})
六、样式控制
支持设置宽度、高度、背景色、边框、阴影、圆角等样式:
new CustomDialogController({
builder: CustomDialogExample(),
width: '80%',
height: '100px',
backgroundColor: 0xd9ffffff,
cornerRadius: 20,
borderWidth: 1,
borderStyle: BorderStyle.Dashed,
borderColor: Color.Blue,
shadow: {
radius: 20,
color: Color.Grey,
offsetX: 50,
offsetY: 0
}
})
七、物理返回拦截
通过 onWillDismiss 回调拦截关闭操作:
new CustomDialogController({
builder: CustomDialogExample(),
onWillDismiss: (action: DismissDialogAction) => {
if (action.reason === DismissReason.PRESS_BACK) {
// 处理逻辑,可调用 action.dismiss() 关闭
}
}
})
八、软键盘避让
从 API Version 15 开始支持:
new CustomDialogController({
builder: CustomDialogExample(),
keyboardAvoidMode: KeyboardAvoidMode.DEFAULT,
keyboardAvoidDistance: LengthMetrics.vp(0) // 与键盘间距
})
备注
-
弹出框关闭后建议在
aboutToDisappear中将controller置空,防止内存泄漏。 -
非模态弹窗允许与页面同时交互,模态弹窗则会阻断页面交互。
1839

被折叠的 条评论
为什么被折叠?



