赞
踩
在我们日常使用应用的时候,可能会进行一些敏感的操作,比如删除联系人,这时候我们给应用添加弹窗来提示用户是否需要执行该操作,如下图所示:
弹窗是一种模态窗口,通常用来展示用户当前需要的或用户必须关注的信息或操作。在弹出框消失之前,用户无法操作其他界面内容。ArkUI为我们提供了丰富的弹窗功能,弹窗按照功能可以分为以下两类:
您可以根据业务场景,选择不同类型的弹窗。部分弹窗效果图如下:
此外,如果上述弹窗还不能满足您的需求,或者需要对弹窗的布局和样式进行自定义,您还可以使用自定义弹窗CustomDialog。
下文将分别介绍AlertDialog 、TextPickerDialog 、DatePickerDialog以及CustomDialog的使用。
警告弹窗AlertDialog由以下三部分区域构成,对应下面的示意图:
以下示例代码,演示了如何使用AlertDialog 实现上图所示的警告弹窗。AlertDialog可以设置两个操作按钮,示例代码中分别使用primaryButton和secondaryButton实现了“取消”和“删除”操作按钮,操作按钮可以通过action响应点击事件。
Button('点击显示弹窗') .onClick(() => { AlertDialog.show( { title: '删除联系人', // 标题 message: '是否需要删除所选联系人?', // 内容 autoCancel: false, // 点击遮障层时,是否关闭弹窗。 alignment: DialogAlignment.Bottom, // 弹窗在竖直方向的对齐方式 offset: { dx: 0, dy: -20 }, // 弹窗相对alignment位置的偏移量 primaryButton: { value: '取消', action: () => { console.info('Callback when the first button is clicked'); } }, secondaryButton: { value: '删除', fontColor: '#D94838', action: () => { console.info('Callback when the second button is clicked'); } }, cancel: () => { // 点击遮障层关闭dialog时的回调 console.info('Closed callbacks'); } } ) })
此外,您还可以使用AlertDialog,构建只包含一个操作按钮的确认弹窗,使用confirm响应操作按钮回调。
AlertDialog.show( { title: '提示', message: '提示信息', autoCancel: true, alignment: DialogAlignment.Bottom, offset: { dx: 0, dy: -20 }, confirm: { value: '确认', action: () => { console.info('Callback when confirm button is clicked'); } }, cancel: () => { console.info('Closed callbacks') } } )
选择类弹窗用于方便用户选择相关数据,比如选择喜欢吃的水果、出生日期等等。下面我们以TextPickerDialog和DatePickerDialog为例,来介绍选择类弹窗的使用。
TextPickerDialog为文本滑动选择器弹窗,根据指定的选择范围创建文本选择器,展示在弹窗上,例如下面这段示例代码使用TextPickerDialog实现了一个水果选择弹窗。示例代码中使用selected指定了弹窗的初始选择项索引为2,对应的数据为“香蕉”。当用户点击“确定”操作按钮后,会触发onAccept事件回调,在回调中将选中的值,传递给宿主中的select变量。
@Entry @Component struct TextPickerDialogDemo { @State select: number = 2; private fruits: string[] = ['苹果', '橘子', '香蕉', '猕猴桃', '西瓜']; build() { Column() { Button("TextPickerDialog") .margin(20) .onClick(() => { TextPickerDialog.show({ range: this.fruits, // 设置文本选择器的选择范围 selected: this.select, // 设置初始选中项的索引值。 onAccept: (value: TextPickerResult) => { // 点击弹窗中的“确定”按钮时触发该回调。 // 设置select为按下确定按钮时候的选中项index,这样当弹窗再次弹出时显示选中的是上一次确定的选项 this.select = value.index; console.info("TextPickerDialog:onAccept()" + JSON.stringify(value)); }, onCancel: () => { // 点击弹窗中的“取消”按钮时触发该回调。 console.info("TextPickerDialog:onCancel()"); }, onChange: (value: TextPickerResult) => { // 滑动弹窗中的选择器使当前选中项改变时触发该回调。 console.info("TextPickerDialog:onChange()" + JSON.stringify(value)); } }) }) } .width('100%') } }
效果图如下:
下面我们介绍另一种常用的选择类弹窗DatePickerDialog,它是日期滑动选择器弹窗,根据指定的日期范围创建日期滑动选择器,展示在弹窗上。DatePickerDialog的使用非常广泛,比如当我们需要输入个人出生日期的时候,就可以使用DatePickerDialog。下面的示例代码实现了一个日期选择弹窗:
@Entry @Component struct DatePickerDialogDemo { selectedDate: Date = new Date("2010-1-1") build() { Column() { Button("DatePickerDialog") .margin(20) .onClick(() => { DatePickerDialog.show({ start: new Date("1900-1-1"), // 设置选择器的起始日期 end: new Date("2023-12-31"), // 设置选择器的结束日期 selected: this.selectedDate, // 设置当前选中的日期 lunar: false, onAccept: (value: DatePickerResult) => { // 点击弹窗中的“确定”按钮时触发该回调 // 通过Date的setFullYear方法设置按下确定按钮时的日期,这样当弹窗再次弹出时显示选中的是上一次确定的日期 this.selectedDate.setFullYear(value.year, value.month, value.day) console.info("DatePickerDialog:onAccept()" + JSON.stringify(value)) }, onCancel: () => { // 点击弹窗中的“取消”按钮时触发该回调 console.info("DatePickerDialog:onCancel()") }, onChange: (value: DatePickerResult) => { // 滑动弹窗中的滑动选择器使当前选中项改变时触发该回调 console.info("DatePickerDialog:onChange()" + JSON.stringify(value)) } }) }) } .width('100%') } }
效果图如下:
自定义弹窗的使用更加灵活,适用于更多的业务场景,在自定义弹窗中您可以自定义弹窗内容,构建更加丰富的弹窗界面。自定义弹窗的界面可以通过装饰器@CustomDialog定义的组件来实现,然后结合CustomDialogController来控制自定义弹窗的显示和隐藏。下面我们通过一个兴趣爱好的选择框来介绍自定义弹窗的使用。
从上面的效果图可以看出,这个选择框是一个多选的列表弹窗,我们可以使用装饰器@CustomDialog,结合List组件来完成这个弹窗布局,实现步骤如下:
初始化弹窗数据。
先准备好资源文件和数据实体类。其中资源文件stringarray.json创建在resources/base/element目录下,文件根节点为strarray。
{ "strarray": [ { "name": "hobbies_data", "value": [ { "value": "Soccer" }, { "value": "Badminton" }, { "value": "Travelling" }, ... ] } ] }
实体类HobbyBean用来封装自定义弹窗中的"兴趣爱好"数据。
export default class HobbyBean {
label: string;
isChecked: boolean;
}
然后创建一个ArkTS文件CustomDialogWidget,用来封装自定义弹窗,使用装饰器@CustomDialog修饰CustomDialogWidget表示这是一个自定义弹窗。使用资源管理对象manager获取数据,并将数据封装到hobbyBeans。
@CustomDialog export default struct CustomDialogWidget { @State hobbyBeans: HobbyBean[] = []; aboutToAppear() { let context: Context = getContext(this); let manager = context.resourceManager; manager.getStringArrayValue($r('app.strarray.hobbies_data'), (error, hobbyResult) => { ... hobbyResult.forEach((hobbyItem: string) => { let hobbyBean = new HobbyBean(); hobbyBean.label = hobbyItem; hobbyBean.isChecked = false; this.hobbyBeans.push(hobbyBean); }); }); } build() {...} }
创建弹窗组件。
controller对象用于控制弹窗的控制和隐藏,hobbies表示弹窗选中的数据结果。setHobbiesValue方法用于筛选出被选中的数据,赋值给hobbies。
@CustomDialog export default struct CustomDialogWidget { @State hobbyBeans: HobbyBean[] = []; @Link hobbies: string; private controller: CustomDialogController; aboutToAppear() {...} setHobbiesValue(hobbyBeans: HobbyBean[]) { let hobbiesText: string = ''; hobbiesText = hobbyBeans.filter((isCheckItem: HobbyBean) => isCheckItem?.isChecked) .map((checkedItem: HobbyBean) => { return checkedItem.label; }).join(','); this.hobbies = hobbiesText; } build() { Column() { Text($r('app.string.text_title_hobbies'))... List() { ForEach(this.hobbyBeans, (itemHobby: HobbyBean) => { ListItem() { Row() { Text(itemHobby.label)... Toggle({ type: ToggleType.Checkbox, isOn: false })... .onChange((isCheck) => { itemHobby.isChecked = isCheck; }) } } }, itemHobby => itemHobby.label) } Row() { Button($r("app.string.cancel_button"))... .onClick(() => { this.controller.close(); }) Button($r("app.string.definite_button"))... .onClick(() => { this.setHobbiesValue(this.hobbyBeans); this.controller.close(); }) } } } }
使用自定义弹窗。
在自定义弹窗的使用页面HomePage中先定义一个变量hobbies,使用装饰器@State修饰,和自定义弹窗中的@Link 装饰器修饰的变量进行双向绑定。然后我们使用alignment和offset设置弹窗的位置在屏幕底部,并且距离底部20vp。最后我们在自定义组件TextCommonWidget(具体实现可以参考《构建多种样式弹窗》Codelab源码)的点击事件中,调用customDialogController的open方法,用于显示弹窗。
@Entry @Component struct HomePage { customDialogController: CustomDialogController = new CustomDialogController({ builder: CustomDialogWidget({ onConfirm: this.setHobbiesValue.bind(this), }), alignment: DialogAlignment.Bottom, customStyle: true, offset: { dx: 0,dy: -20 } }); setHobbiesValue(hobbyArray: HobbyBean[]) {...} build() { ... TextCommonWidget({ ... title: $r("app.string.title_hobbies"), content: $hobby, onItemClick: () => { this.customDialogController.open(); } }) ... } }
关于更多弹窗,您可以参考:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。