自定义弹窗
自定义弹窗(CustomDialog)简易使用
自定义弹窗是 HarmonyOS 提供的一种弹窗组件,可通过CustomDialogController
类来显示。以下是其简易使用方法:
1. 基本概念
从 API Version 7 开始支持,在元服务中从 API version 11 开始支持。它允许开发者自定义弹窗的样式与内容,适用于简单提示场景,但不能替代页面。
2. 重要接口及参数
-
constructor(value: CustomDialogControllerOptions)
:配置自定义弹窗参数,所有参数不支持动态刷新。
builder
:必填,自定义弹窗内容构造器。使用回调函数作为入参时注意this
绑定问题,监听数据变化用@Link
。cancel
:可选,返回、ESC 键和点击遮障层弹窗退出时的回调。autoCancel
:可选,默认true
,是否允许点击遮障层退出。alignment
:可选,弹窗竖直方向对齐方式,默认DialogAlignment.Default
。offset
:可选,弹窗相对alignment
所在位置偏移量,默认{ dx: 0, dy: 0 }
。customStyle
:可选,控制弹窗容器样式是否自定义,影响圆角、宽度高度等设置。gridCount
:可选,弹窗宽度占栅格宽度个数,默认自适应。- 还有更多参数如
maskColor
(蒙层颜色)、maskRect
(遮蔽层区域)、openAnimation
(弹出动画)、closeAnimation
(关闭动画)等,从 API version 10 或 12 开始支持,用于更精细的弹窗样式和行为控制。
3. 使用步骤
- 创建弹窗内容构造器
- 使用
@CustomDialog
和@Component
装饰器定义结构体,在build
方法中构建弹窗内容,如文本、按钮等。
- 使用
- 配置弹窗参数并创建
CustomDialogController
实例- 在父组件中创建
CustomDialogController
实例,传入包含builder
及其他可选参数的配置对象。
- 在父组件中创建
- 显示和关闭弹窗
- 通过
CustomDialogController
的open
方法显示弹窗,close
方法关闭弹窗。在弹窗内容构造器中或父组件中响应按钮点击等事件来调用这些方法。
- 通过
4. 示例代码解读
以下是示例代码片段及解释:
// 定义第二个弹窗结构体
@CustomDialog
struct CustomDialogExampleTwo {
controllerTwo?: CustomDialogController
build() {
Column() {
Text('我是第二个弹窗')
.fontSize(30)
.height(100)
Button('点我关闭第二个弹窗')
.onClick(() => {
// 关闭第二个弹窗
if (this.controllerTwo!= undefined) {
this.controllerTwo.close()
}
})
.margin(20)
}
}
}
// 定义第一个弹窗结构体,包含第二个弹窗的控制器
@CustomDialog
@Component
struct CustomDialogExample {
@Link textValue: string
@Link inputValue: string
dialogControllerTwo: CustomDialogController | null = new CustomDialogController({
builder: CustomDialogExampleTwo(),
alignment: DialogAlignment.Bottom,
onWillDismiss:(dismissDialogAction: DismissDialogAction)=> {
// 处理弹窗即将关闭的回调
console.info("reason=" + JSON.stringify(dismissDialogAction.reason))
console.log("dialog onWillDismiss")
if (dismissDialogAction.reason == DismissReason.PRESS_BACK) {
dismissDialogAction.dismiss()
}
if (dismissDialogAction.reason == DismissReason.TOUCH_OUTSIDE) {
dismissDialogAction.dismiss()
}
},
offset: { dx: 0, dy: -25 }
})
controller?: CustomDialogController
cancel: () => void = () => {}
confirm: () => void = () => {}
build() {
Column() {
Text('Change text').fontSize(20).margin({ top: 10, bottom: 10 })
TextInput({ placeholder: '', text: this.textValue }).height(60).width('90%')
.onChange((value: string) => {
this.textValue = value
})
Text('Whether to change a text?').fontSize(16).margin({ bottom: 10 })
Flex({ justifyContent: FlexAlign.SpaceAround }) {
Button('cancel')
.onClick(() => {
if (this.controller!= undefined) {
this.controller.close()
this.cancel()
}
}).backgroundColor(0xffffff).fontColor(Color.Black)
Button('confirm')
.onClick(() => {
if (this.controller!= undefined) {
this.inputValue = this.textValue
this.controller.close()
this.confirm()
}
}).backgroundColor(0xffffff).fontColor(Color.Red)
}.margin({ bottom: 10 })
Button('点我打开第二个弹窗')
.onClick(() => {
if (this.dialogControllerTwo!= null) {
this.dialogControllerTwo.open()
}
})
.margin(20)
}.borderRadius(10)
}
}
// 入口组件,包含第一个弹窗的控制器
@Entry
@Component
struct CustomDialogUser {
@State textValue: string = ''
@State inputValue: string = 'click me'
dialogController: CustomDialogController | null = new CustomDialogController({
builder: CustomDialogExample({
cancel: ()=> { this.onCancel() },
confirm: ()=> { this.onAccept() },
textValue: $textValue,
inputValue: $inputValue
}),
cancel: this.exitApp,
autoCancel: true,
onWillDismiss:(dismissDialogAction: DismissDialogAction)=> {
console.info("reason=" + JSON.stringify(dismissDialogAction.reason))
console.log("dialog onWillDismiss")
if (dismissDialogAction.reason == DismissReason.PRESS_BACK) {
dismissDialogAction.dismiss()
}
if (dismissDialogAction.reason == DismissReason.TOUCH_OUTSIDE) {
dismissDialogAction.dismiss()
}
},
alignment: DialogAlignment.Bottom,
offset: { dx: 0, dy: -20 },
gridCount: 4,
customStyle: false,
cornerRadius: 10,
})
// 在组件即将销毁时将弹窗控制器置空
aboutToDisappear() {
this.dialogController = null
}
onCancel() {
console.info('Callback when the first button is clicked')
}
onAccept() {
console.info('Callback when the second button is clicked')
}
exitApp() {
console.info('Click the callback in the blank area')
}
build() {
Column() {
Button(this.inputValue)
.onClick(() => {
if (this.dialogController!= null) {
this.dialogController.open()
}
}).backgroundColor(0x317aff)
}.width('100%').margin({ top: 5 })
}
}
在这个示例中:
- 定义了两个弹窗结构体
CustomDialogExample
和CustomDialogExampleTwo
,CustomDialogExample
中包含CustomDialogExampleTwo
的控制器,实现了弹窗嵌套。 - 在
CustomDialogExample
和CustomDialogUser
中分别配置了弹窗参数,如对齐方式、偏移量、网格数、圆角半径等。 - 通过按钮的点击事件来控制弹窗的打开和关闭,同时处理了弹窗关闭的回调和即将关闭的拦截操作。
5. 注意事项
- 弹窗在避让软键盘时到达极限高度后会压缩高度,但高度压缩生效在外层容器上,若子组件设置较大固定高度,可能存在超出屏幕显示情况。
- ArkUI 弹窗在页面路由跳转时,若未手动关闭,不会自动关闭,如需同步关闭,建议使用
Navigation
。 - 使用某些参数时需注意其默认值和相关限制,如
borderWidth
、borderColor
、borderStyle
需一起使用,backgroundColor
与backgroundBlurStyle
的设置关系等。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!