Appearance
弹窗与对话框
ArkUI 提供多种弹窗组件,各有不同的使用场景和 API。
1. 弹窗组件分类
弹窗体系
├── Dialog(系统弹窗)
├── CustomDialogController(自定义弹窗)
├── Popup(弹出框)
├── ActionSheet(底部操作面板)
└── PromptActionSheet(底部提示面板)2. Dialog — 系统弹窗
2.1 基本用法
typescript
@Entry
@Component
struct Index {
private dialogController: DialogController = new DialogController({
autoCancel: true, // 点击外部是否关闭
alignment: DialogAlignment.Center, // 对齐方式
offset: { dx: 0, dy: 0 }
})
build() {
Column() {
Button('打开系统弹窗')
.onClick(() => {
this.dialogController.open(
// 内容
() => {
Text('确定要删除这条数据吗?')
.fontSize(18fp)
},
// 按钮列表
[
{
action: '取消',
actionChild: () => this.dialogController.close()
},
{
action: '删除',
actionChild: () => {
// 执行删除逻辑
this.dialogController.close()
}
}
],
// 配置
{ cancel: () => this.dialogController.close() }
)
})
}
}
}2.2 对齐方式
| 方式 | 说明 |
|---|---|
DialogAlignment.Top | 顶部居中 |
DialogAlignment.Bottom | 底部居中 |
DialogAlignment.Center | 居中 |
DialogAlignment.Start | 左侧居中 |
DialogAlignment.End | 右侧居中 |
3. CustomDialogController — 自定义弹窗 ⭐
3.1 弹窗内容定义
typescript
@CustomDialog
struct ConfirmDialog {
controller: CustomDialogController
@State title: string = '提示'
@State content: string = '确定操作吗?'
build() {
Column() {
Text(this.title)
.fontSize(20fp)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 16 })
.textAlign(TextAlign.Center)
Divider().margin({ bottom: 16 })
Text(this.content)
.fontSize(16fp)
.textAlign(TextAlign.Center)
.margin({ bottom: 24 })
Row() {
Button('取消')
.width('48%')
.onClick(() => this.controller.close())
Button('确定')
.width('48%')
.onClick(() => {
// 执行操作
this.controller.close()
})
}
.width('100%')
}
.width('80%')
.padding(24)
.borderRadius(12)
.backgroundColor(Color.White)
}
}3.2 弹窗控制器配置
typescript
@Entry
@Component
struct Index {
private dialogController = new CustomDialogController({
builder: ConfirmDialog({
controller: null as any,
title: '删除确认',
content: '删除后不可恢复,确定吗?'
}),
alignment: DialogAlignment.Center,
offset: { dx: 0, dy: 0 },
autoCancel: true,
customPanelState: CustomPanelState.POPUP, // POPUP/DRAG
width: CustomPanelWidth.MATCH_PARENT,
cornerType: CornerType.ALL,
showCloseButton: false,
autoCancelOutside: true
})
build() {
Column() {
Button('打开自定义弹窗')
.onClick(() => {
this.dialogController.open()
})
}
}
}3.3 CustomPanelState
| 状态 | 说明 |
|---|---|
CustomPanelState.POPUP | 弹窗模式(标准弹出) |
CustomPanelState.DRAG | 可拖拽面板(从底部弹出) |
4. Popup — 弹出框
4.1 基本用法
typescript
@Entry
@Component
struct Index {
private controller: PopupController = new PopupController({
alignment: PopupAlignment.Bottom,
offset: { dx: 0, dy: 0 },
popover: {
contentColor: Color.White,
shape: PopoverShape.CIRCLE, // CIRCLE/ROUND_RECT
cornerRadius: 8,
width: 200,
height: 150,
margin: 10
}
})
build() {
Column() {
// 触发按钮
Button('弹出菜单')
.onClick(() => {
this.controller.open(() => {
// 弹出框内容
Column() {
Text('选项1').onClick(() => this.controller.close())
Text('选项2').onClick(() => this.controller.close())
Text('选项3').onClick(() => this.controller.close())
}
})
})
// 定位标记
this.controller.reference('popup')
}
.width('100%')
.height('100%')
}
}4.2 弹出位置
| 位置 | 值 |
|---|---|
| 底部居中 | PopupAlignment.Bottom |
| 顶部居中 | PopupAlignment.Top |
| 左侧居中 | PopupAlignment.Start |
| 右侧居中 | PopupAlignment.End |
5. ActionSheet — 底部操作面板
5.1 基本用法
typescript
@Entry
@Component
struct Index {
private actionSheetController = new ActionSheetController({
items: ['拍照', '从相册选择', '取消'],
cancelTitle: '取消',
destructiveIndex: -1
})
build() {
Column() {
Button('打开底部菜单')
.onClick(() => {
this.actionSheetController.open((index) => {
if (index === 0) {
console.log('拍照')
} else if (index === 1) {
console.log('相册')
}
})
})
}
}
}5.2 配置项
| 配置 | 说明 |
|---|---|
items | 菜单项列表 |
cancelTitle | 取消按钮文字 |
destructiveIndex | 危险操作的索引(红色文字) |
disabledIndex | 禁用的索引 |
showCancel | 是否显示取消按钮 |
6. 弹窗最佳实践
6.1 弹窗与组件通信
typescript
// 父组件传递回调
@Entry
@Component
struct Index {
private dialogController = new CustomDialogController({
builder: ConfirmDialog({
controller: null as any,
onConfirm: () => {
// 确认回调
console.log('用户确认了')
}
}),
alignment: DialogAlignment.Center
})
build() {
Column() {
Button('确认弹窗')
.onClick(() => this.dialogController.open())
}
}
}
// 弹窗内容
@CustomDialog
struct ConfirmDialog {
controller: CustomDialogController
onConfirm: () => void = () => {}
build() {
Column() {
Button('确定')
.onClick(() => {
this.onConfirm() // 调用父组件回调
this.controller.close()
})
}
}
}6.2 弹窗生命周期管理
typescript
@Component
struct LifecycleAwareDialog {
controller: CustomDialogController
aboutToAppear() {
console.log('弹窗显示')
// 弹窗打开后的初始化
}
aboutToDisappear() {
console.log('弹窗关闭')
// 弹窗关闭后的清理
}
build() {
// ...
}
}7. 面试高频考点
Q1: 鸿蒙有哪些弹窗组件?
回答:Dialog(系统弹窗)、CustomDialogController(自定义弹窗)、Popup(弹出框)、ActionSheet(底部操作面板)、PromptActionSheet(底部提示面板)。
Q2: CustomDialogController 的 customPanelState 有哪些?
回答:POPUP(标准弹窗)和 DRAG(可拖拽面板,从底部弹出)。
Q3: 弹窗关闭的时机和清理?
回答:在 aboutToDisappear 生命周期中清理弹窗相关资源,如定时器、监听器等。
🐱 小猫提示:弹窗部分记住 "CustomDialogController 最灵活、ActionSheet 最便捷、Dialog 最标准"。面试中重点说 CustomDialog 的使用。