鸿蒙中级课程笔记3—ArkUI进阶2—给应用添加交互(弹窗)
弹窗概述
弹窗一般指打开应用时自动弹出或者用户行为操作时弹出的UI界面,用于短时间内展示用户需关注的信息或待处理的操作。
从ArkUI组件树层级上来看,Overlay浮层、弹窗、模态、带Order的Overlay浮层都挂载在Root节点下。弹窗、模态、带Order的Overlay浮层根据设置的层级(数字大小)进行逐层显示,并且全部显示在Overlay浮层上面。如图所示:

对于一个多页面应用,基本树结构如下所示。多个Page页面之间使用Router的接口进行跳转。NavBar和Navdestination组成的页面可以通过Navigation接口进行跳转。

而Dialog、Popup、Menu、OverlayManager、Toast、bindSheet以及bindContentCover的组件在结合路由、导航使用时存在如下几种显示模式。
-
弹窗显示在当前应用窗口最上层,层级高于应用主窗内所有页面(默认行为)。
如下图所示,触发弹窗显示时,弹窗层级要高于Page页面和Navigation页面,即如果弹窗组件没有被关闭的话,页面切换前后,弹窗组件都会显示在页面上方,而不会出现新的路由/导航页面覆盖在弹窗之上的情况。

说明
如果Popup或Menu等存在绑定组件的弹窗组件,在页面跳转后因为所绑定的组件不在新页面显示,系统内部会自动关闭对应弹窗组件。但因为弹窗组件显示同时受开发者配置的参数控制,例如当Popup的show参数设置为显示时,弹窗组件会覆盖在下一个页面上显示。
-
弹窗显示在当前页面内,层级低于下一跳页面。
当开发者期望弹窗是一个页面内的弹窗,即当路由/导航切换页面时,弹窗会被跳转的页面覆盖,随着页面切回原页面,弹窗仍然正常显示。此时弹窗层级如下图所示:

-
弹窗显示在独立窗口内,窗口层级高于应用所在窗口。
在PC/2in1等设备上,开发者常期望弹窗的显示在应用窗口之外,此时需要借助子窗的能力。例如自定义弹窗可以通过CustomDialogControllerOptions中的showInSubwindow属性控制是否使用子窗功能。基于子窗显示的弹窗效果如下图所示。

此时弹窗组件的显示层级受窗口的层级管理控制,会高于当前应用所在的窗口,低于系统窗口(如系统输入法、系统弹窗等)。
弹窗的种类
根据用户交互操作场景,弹窗可分为模态弹窗和非模态弹窗两种类型,其区别在于用户是否必须对其做出响应。
- 模态弹窗: 为强交互形式,会中断用户当前的操作流程,要求用户必须做出响应才能继续其他操作,通常用于需要向用户传达重要信息的场景。
- 非模态弹窗: 为弱交互形式,不会影响用户当前操作行为,用户可以不对其进行回应,通常都有时间限制,出现一段时间后会自动消失。一般用于告诉用户信息内容外还需要用户进行功能操作的场景。
说明
当前模态弹窗通过设置指定属性变成非模态,例如AlertDialog,可以设置AlertDialogParam中的isModal属性值为false变成非模态,其他弹窗详见API说明。
不建议在非前台状态下,调用弹窗显示接口。
系统弹窗由系统弹出,出于安全考虑,不支持自定义样式。
系统弹窗出现时,调用非系统弹窗的显示接口(例如:promptAction的openCustomDialog、CustomDialogController的open等),禁止该类弹窗显示。
使用场景
开发者可根据实际应用场景选择合适的弹窗进行页面开发。
| 弹窗名称 | 应用场景 |
|---|---|
| 弹出框(Dialog) | 当需要展示用户当前需要或必须关注的信息内容或操作时,例如二次退出应用等,应优先考虑使用此弹出框。 |
| 菜单(Menu/openMenu) | 当需要给用户提供可执行的操作时,例如长按图标展示操作选项等,应优先考虑使用此弹窗。 |
| 气泡提示(Popup/openPopup) | 当需要给用户提供提示时,例如点击一个问号图标弹出一段帮助提示等,应优先考虑使用此弹窗。 |
| 绑定模态页面(bindContentCover/bindSheet) | 当需要新的界面覆盖在旧的界面上,且旧的界面不消失的一种转场方式时,例如缩略图片点击后查看大图等,应优先考虑使用此弹窗。 |
| 即时反馈(Toast) | 当需要在一个小的窗口中提供用户当前操作的简单反馈时,例如提示文件保存成功等,应优先考虑使用此弹窗。 |
| 设置浮层(OverlayManager) | 当需要完全自定义内容、行为、样式时,可以使用浮层将UI展示在页面之上,例如音乐/语音播放悬浮球/胶囊等,应优先考虑使用此弹窗。 |
规格约束
-
多个弹窗组件先后弹出时,后弹出的组件的层级高于先弹出的层级,退出时按照层级从高到低的顺序逐次退出。
-
在移动设备中,子窗模式的弹窗当前无法超出主窗口。而在2in1设备上,使用模态类弹窗时,会出现需要超出主窗口显示的场景,开发者可以通过设置showInSubWindow为true实现超出主窗口的显示效果。如下图所示:

固定样式弹框
固定样式弹出框采用固定的布局格式,这使得开发者无需关心具体的显示布局细节,只需输入所需显示的文本内容,从而简化了使用流程,提升了便捷性。

接口概览

使用约束
-
可以通过调用UIContext或getUIContext,在非UI页面或某些异步回调中使用本文中的接口。CalendarPickerDialog当前不支持此操作。
-
操作菜单 (showActionMenu)、对话框 (showDialog)需先使用UIContext中的getPromptAction()方法获取到PromptAction对象,再通过该对象调用对应方法。
-
列表选择弹出框 (ActionSheet)、警告弹出框 (AlertDialog)、选择器弹出框 (PickerDialog)中除CalendarPickerDialog都需先使用ohos.window中的getUIContext()方法获取UIContext实例,再通过此实例调用对应方法。或者可以通过自定义组件内置方法getUIContext()获取。
操作菜单 (showActionMenu)、对话框 (showDialog)、列表选择弹出框 (ActionSheet)、警告弹出框 (AlertDialog)可以设置isModal为false变成非模态弹窗。
操作菜单 (showActionMenu)、对话框 (showDialog)、列表选择弹出框 (ActionSheet)和警告弹出框 (AlertDialog)不支持设置内容区的字体样式,如字体颜色、大小换行等操作,如需自定义样式,建议使用不依赖UI组件的全局自定义弹出框或者基础自定义弹出框。
注意:不是所有固定弹框都不能设置样式,只能设置部分内容样式,每个固定弹框允许设置的内容样式内容不一样,需要具体参考各固定弹窗的指南。
生命周期
弹出框提供了生命周期函数,用于通知用户该弹出框的生命周期。生命周期的触发时序依次为:onWillAppear -> onDidAppear -> onWillDisappear -> onDidDisappear,也可参照各组件API。
从API version 19开始,对话框(showDialog)、列表选择弹出框(ActionSheet)、警告弹出框(AlertDialog)支持以下生命周期。
| 名称 | 类型 | 说明 |
|---|---|---|
| onWillAppear | Callback<void> | 弹出框显示动效前的事件回调。 |
| onDidAppear | Callback<void> | 弹出框弹出后的事件回调。 |
| onWillDisappear | Callback<void> | 弹出框退出动效前的事件回调。 |
| onDidDisappear | Callback<void> | 弹出框消失后的事件回调。 |
即时反馈(Toast)
使用步骤
- 页面中通过import导入PromptAction:import { PromptAction } from '@kit.ArkUI';
-
通过使用UIContext中的getPromptAction获取当前UI上下文关联的PromptAction对象:private promptAction: PromptAction = this.uicontext.getPromptAction();
-
再通过该对象调用showToast创建并显示文本提示框
this.promptAction.showToast({
message:‘保存成功',//弹窗显示内容
duration: 2000//弹窗显示时间
})
显示模式

操作菜单 (showActionMenu)
操作菜单通过UIContext中的getPromptAction方法获取到PromptAction对象,再通过该对象调用showActionMenu接口实现,支持在回调或开发者自定义类中使用。
操作菜单中,title字段的字体最大放大倍数为2。
创建并显示操作菜单后,菜单的响应结果会异步返回选中按钮在buttons数组中的索引。
例子参考固定样式弹框


对话框 (showDialog)
对话框通过UIContext中的getPromptAction方法获取到PromptAction对象,再通过该对象调用showDialog接口实现,支持在回调或开发者自定义类中使用。
对话框中,title字段的字体最大放大倍数为2。
创建并显示对话框,对话框响应后异步返回选中按钮在buttons数组中的索引。
例子参考固定样式弹框

选择器弹窗 (PickerDialog)
选择器弹窗通常用于在用户进行某些操作(如点击按钮)时显示特定的信息或选项。
日历选择器弹窗 (CalendarPickerDialog)
日历选择器弹窗提供日历视图,包含年、月和星期信息,通过CalendarPickerDialog接口实现。开发者可调用show函数,定义并弹出日历选择器弹窗。
日历选择器弹窗的弹出依赖UI的执行上下文,不可在UI上下文不明确的地方使用,具体约束参见UIContext说明。
通过配置CalendarDialogOptions中的acceptButtonStyle、cancelButtonStyle属性可以实现自定义按钮样式。
例子参考固定样式弹框

日期滑动选择器弹窗 (DatePickerDialog)
开发者可以利用指定的日期范围,创建日期滑动选择器弹窗,将日期信息清晰地展示在弹出的窗口上。
日期滑动选择器弹窗通过UIContext中的showDatePickerDialog接口实现。
弹窗中配置DatePickerDialogOptions的lunarSwitch、showTime属性为true时,会展示切换农历的开关和时间,当checkbox被选中时,会显示农历。当按下确定按钮时,弹窗会通过onDateAccept返回目前所选中的日期。如需弹窗再次弹出时显示选中的是上一次确定的日期,就要在回调中重新给selectTime进行赋值。
例子参考固定样式弹框

通过配置disappearTextStyle、textStyle、selectedTextStyle、acceptButtonStyle、cancelButtonStyle实现了自定义文本以及按钮样式。 例子参考固定样式弹框,如下图

时间滑动选择器弹窗 (TimePickerDialog)
开发者可根据24小时的时间区间,创建时间滑动选择器弹窗,将时间信息清晰地展示在弹出的窗口上。
时间滑动选择器弹窗通过UIContext中的showTimePickerDialog接口实现。
该示例通过配置disappearTextStyle、textStyle、selectedTextStyle、acceptButtonStyle、cancelButtonStyle实现了自定义文本以及按钮样式。 例子参考固定样式弹框
文本滑动选择器弹窗 (TextPickerDialog)
开发者可根据指定的选择范围,创建文本滑动选择器弹窗,将文本信息清晰地展示在弹出的窗口上。
文本滑动选择器弹窗通过UIContext中的showTextPickerDialog接口实现。

示例中通过设置range的参数类型为TextCascadePickerRangeContent[],实现3列文本选择器弹窗。当按下确定按钮时,弹窗会通过onAccept返回目前所选中文本和索引值。如需弹窗再次弹出时显示选中的是上一次确定的文本,就要在回调中重新给select进行赋值。 例子参考固定样式弹框
列表选择弹窗 (ActionSheet)
列表选择器弹窗适用于呈现多个操作选项,尤其当界面中仅需展示操作列表而无其他内容时。
列表选择器弹窗通过UIContext中的showActionSheet接口实现。
列表选择弹窗中,title字段的字体最大放大倍数为2。
该示例通过配置width、height、transition等接口,定义了弹窗的样式以及弹出动效。 例子参考固定样式弹框

警告弹窗 (AlertDialog)
向用户提问或得到用户的许可时,使用警告弹窗。
- 警告弹窗用来提示重要信息,但会中断当前任务,尽量提供必要的信息和有用的操作。
- 避免仅使用警告弹窗提供信息,用户不喜欢被信息丰富但不可操作的警告打断。
警告弹窗通过UIContext中的showAlertDialog接口实现。
警告弹窗中,title和subtitle字段的字体最大放大倍数为2。
该示例通过配置width、height、transition等接口,定义了多个按钮弹窗的样式以及弹出动效。例子参考固定样式弹框
不依赖UI组件的全局自定义弹框
在广告、中奖、警告、软件更新等与用户交互响应操作的场景下,可以使用UIContext中获取到的PromptAction对象提供的openCustomDialog接口来实现自定义弹出框。相较于CustomDialogController优势点在于页面解耦,支持动态刷新。
说明
弹出框(openCustomDialog)存在两种入参方式创建自定义弹出框:
- openCustomDialog(传参为ComponentContent形式):通过ComponentContent封装内容可以与UI界面解耦,调用更加灵活,可以满足开发者的封装诉求。具有较高的灵活性,弹出框样式完全自定义,并且在弹出框打开后可以使用updateCustomDialog方法动态更新弹出框的参数。
- openCustomDialog(传参为builder形式):相对于ComponentContent,builder必须要与上下文做绑定,与UI存在一定耦合。此方法有默认的弹出框样式,适合于开发者想要实现与系统弹窗默认风格一致的效果。
本文介绍通过入参形式为ComponentContent创建自定义弹出框,传builder形式的弹出框使用方法可参考openCustomDialog。
弹出框(openCustomDialog)默认为模态弹窗且有蒙层,不可与蒙层下方控件进行交互(不支持点击和手势等向下透传)。可以通过配置promptAction.BaseDialogOptions类型中的isModal属性来实现模态和非模态弹窗,详细说明可参考弹窗的种类。
当isModal为true时,弹出框为模态弹窗,且弹窗周围的蒙层区不支持透传。isModal为false时,弹出框为非模态弹窗,且弹窗周围的蒙层区可以透传。因此如果需要同时允许弹出框的交互和弹出框外页面的交互行为,需要将弹出框设置为非模态。
生命周期
弹出框提供了生命周期函数用于通知用户该弹出框的生命周期。生命周期的触发时序依次为:onWillAppear -> onDidAppear -> onWillDisappear -> onDidDisappear。
| 名称 | 类型 | 说明 |
|---|---|---|
| onDidAppear | () => void | 弹出框弹出后的事件回调。 |
| onDidDisappear | () => void | 弹出框消失后的事件回调。 |
| onWillAppear | () => void | 弹出框显示动效前的事件回调。 |
| onWillDisappear | () => void | 弹出框退出动效前的事件回调。 |
接口概述

创建并弹出自定义弹框接口及参数说明
更新自定义弹框接口及参数说明

对自定义弹窗示例代码的讲解参考视频课程16分钟处
自定义弹出框的打开与关闭
说明
详细变量定义请参考完整示例。
-
创建ComponentContent。
ComponentContent用于定义自定义弹出框的内容。其中,wrapBuilder(buildText)封装自定义组件,new Params(this.message)是自定义组件的入参,可以缺省,也可以传入基础数据类型。
-
打开自定义弹出框。
调用openCustomDialog接口打开的弹出框默认customStyle为true,即弹出框的内容样式完全按照contentNode自定义样式显示。
-
关闭自定义弹出框。
由于closeCustomDialog接口需要传入待关闭弹出框对应的ComponentContent。因此,如果需要在弹出框中设置关闭方法,则可参考完整示例封装静态方法来实现。
关闭弹出框之后若需要释放对应的ComponentContent,则需要调用ComponentContent的dispose方法。
更新自定义弹出框的内容
ComponentContent与BuilderNode有相同的使用限制,不支持自定义组件使用@Reusable、@Link、@Provide、@Consume等装饰器,来同步弹出框弹出的页面与ComponentContent中自定义组件的状态。因此,若需要更新弹出框中自定义组件的内容可以通过ComponentContent提供的update方法来实现。
更新自定义弹出框的属性
通过updateCustomDialog可以动态更新弹出框的属性。目前支持更新弹出框的对齐方式、基于对齐方式的偏移量、是否点击蒙层自动关闭以及蒙层颜色,对应的属性分别为BaseDialogOptions中的alignment、offset、autoCancel和maskColor。
更新属性时,未设置的属性会恢复为默认值。例如,初始设置{ alignment: DialogAlignment.Top, offset: { dx: 0, dy: 50 } },更新时设置{ alignment: DialogAlignment.Bottom },则初始设置的offset: { dx: 0, dy: 50 }不会保留,会恢复为默认值。
为弹出框内容和蒙层设置不同的动画效果
当弹出框出现时,内容与蒙层显示动效一致。若开发者希望为弹出框内容及蒙层设定不同动画效果,从API version 19开始,可通过BaseDialogOptions中dialogTransition和maskTransition属性单独配置弹窗内容与蒙层的动画。具体的动画效果请参考组件内转场 (transition)。
说明
当isModal为true时,蒙层将显示,此时可以设置蒙层的动画效果;否则,maskTransition将不生效。
设置弹出框避让软键盘的距离
为显示弹出框的独立性,弹出框弹出时会与周边进行避让,包括状态栏、导航条以及键盘等留有间距。故当软键盘弹出时,默认情况下,弹出框会自动避开软键盘,并与之保持16vp的距离。从API version 15开始,开发者可以利用BaseDialogOptions中的keyboardAvoidMode和keyboardAvoidDistance这两个配置项,来设置弹出框在软键盘弹出时的行为,包括是否需要避开软键盘以及与软键盘之间的距离。
设置软键盘间距时,需要将keyboardAvoidMode值设为KeyboardAvoidMode.DEFAULT。
基于ArkUI实现多种样式弹框功能
本篇Codelab主要介绍如何给应用添加各种类型的弹窗,弹窗主要包括气泡提示(Popup)、即时反馈(Toast)、固定样式弹出框、自定义弹窗等。帮助开发者了解各种弹窗的类型,并掌握对应的使用方法。
相关概念
- 气泡提示(Popup):主要用于屏幕录制、信息弹出提醒等显示状态。
- 即时反馈(Toast):用于向用户显示简短的操作反馈或状态信息。
- 固定样式弹出框:是系统提供的标准化弹窗,具有固定的样式和交互方式。
- 自定义弹窗:样式、布局、内容和行为可以根据应用场景进行个性化定制。
各案例代码参考基于ArkUI实现多种样式弹框功能
气泡提示(Popup)的实现
Row() {
Image($r('app.media.dot_grid'))
.width(24)
.height(24)
}
.onClick(() => {
this.customPopup = !this.customPopup
})
.bindPopup(this.customPopup, {
builder: this.PopupBuilder, // Bubble content
placement: Placement.Bottom, // The pop position of the bubble
onStateChange: (e) => {
if (!e.isVisible) {
this.customPopup = false;
}
}
})
即时反馈(Toast)的实现
Row({ space: 2 }) {
Text($r('app.string.save'))
.fontSize(16)
.opacity(0.9)
}
.width(200)
.height(50)
.padding(16)
.onClick(() => {
this.ctx.getPromptAction().showToast({
message: $r('app.string.save_successfully'),
duration: 2000
})
})
固定样式弹出框的实现
日期滑动选择器弹窗的实现
this.getUIContext().showDatePickerDialog({
start: new Date('1925-1-1'),
end: new Date('2055-12-31'),
selected: this.selectTime,
lunarSwitch: true,
showTime: false,
onDateAccept: (value: Date) => {
this.selectTime = value;
let birthDateArray = JSON.stringify(value).slice(1, 11).split('-');
let year = Number(birthDateArray[0]);
let month = Number(birthDateArray[1]);
let day = Number(birthDateArray[2]);
this.birthDate = CommonUtils.getBirthDateValue(year, month, day);
}
})
文本滑动选择器弹窗的实现
this.getUIContext().showTextPickerDialog({
range: this.sexArray,
selected: this.select,
canLoop: false,
onAccept: (value: TextPickerResult) => {
this.select = value.index as number;
this.sex = value.value as string;
},
onChange: (value: TextPickerResult) => {
this.select = value.index as number;
}
})
自定义弹窗的实现
更多推荐



所有评论(0)