弹窗是一种模态窗口,通常用来展示用户当前需要的或用户必须关注的信息或操作。在弹出框消失之前,用户无法操作其他界面内容。ArkUI 为我们提供了丰富的弹窗功能,弹窗按照功能可以分为以下两类:
确认类:例如警告弹窗 AlertDialog。
选择类:包括文本选择弹窗 TextPickerDialog 、日期滑动选择弹窗 DatePickerDialog、时间滑动选择弹窗 TimePickerDialog 等。
您可以根据业务场景,选择不同类型的弹窗。
参考:OpenHarmony 弹窗文档V4.0
今天我们主要了解一下自定义弹窗的使用
自定义弹窗
自定义弹窗的使用更加灵活,适用于更多的业务场景,在自定义弹窗中您可以自定义弹窗内容,构建更加丰富的弹窗界面。自定义弹窗的界面可以通过装饰器@CustomDialog 定义的组件来实现,然后结合 CustomDialogController 来控制自定义弹窗的显示和隐藏。
1、定义自定义弹窗
@CustomDialog
struct CustomDialogExample {// 双向绑定传值@Prop title: string@Link inputValue: string// 弹窗控制器,控制打开/关闭,必须传入,且名称必须为:controllercontroller: CustomDialogController// 弹窗中的按钮事件cancel: () => voidconfirm: () => void// 弹窗中的内容描述build() {Column() {Text(this.title || "是否修改文本框内容?").fontSize(16).margin(24).textAlign(TextAlign.Start).width("100%")TextInput({ placeholder: '文本输入框', text: this.inputValue}).height(60).width('90%').onChange((value: string) => {this.textValue = value})Flex({ justifyContent: FlexAlign.SpaceAround }) {Button('取消').onClick(() => {this.controller.close()this.cancel()}).backgroundColor(0xffffff).fontColor(Color.Black)Button('确定').onClick(() => {this.controller.close()this.confirm()}).backgroundColor(0xffffff).fontColor(Color.Red)}.margin({ bottom: 10 })}}
}
2、使用自定义弹窗
@Entry
@Component
struct Index {@State title: string = '标题'@State inputValue: string = '文本框父子组件数据双绑'// 定义自定义弹窗的Controller,传入参数和回调函数dialogController: CustomDialogController = new CustomDialogController({builder: CustomDialogExample({cancel: this.onCancel,confirm: this.onAccept,textValue: $textValue,inputValue: $inputValue}),cancel: this.existApp,autoCancel: true,alignment: DialogAlignment.Bottom,offset: { dx: 0, dy: -20 },gridCount: 4,customStyle: false})aboutToDisappear() {this.dialogController = undefined // 将dialogController置空}onCancel() {console.info('点击取消按钮', this.inputValue)}onAccept() {console.info('点击确认按钮', this.inputValue)}build() {Column() {Button('打开自定义弹窗').width('60%').margin({top:320}).zIndex(999).onClick(()=>{if (this.dialogController != undefined) {this.dialogController.open()}})}.height('100%').width('100%')
}
3、一个完整的示例(常用网站选择)
export interface HobbyBean {label: string;isChecked: boolean;
}export type DataItemType = { value: string }@Extend(Button) function dialogButtonStyle() {.fontSize(16).fontColor("#007DFF").layoutWeight(1).backgroundColor(Color.White).width(500).height(40)
}@CustomDialog
struct CustomDialogWidget {@State hobbyBeans: HobbyBean[] = [];@Prop title:string;@Prop hobbyResult: Array<DataItemType>;@Link hobbies: string;private controller: CustomDialogController;setHobbiesValue(hobbyBeans: HobbyBean[]) {let hobbiesText: string = '';hobbiesText = hobbyBeans.filter((isCheckItem: HobbyBean) =>isCheckItem?.isChecked).map((checkedItem: HobbyBean) => {return checkedItem.label;}).join(',');this.hobbies = hobbiesText;}aboutToAppear() {// let context: Context = getContext(this);// let manager = context.resourceManager;// manager.getStringArrayValue($r('app.strarray.hobbies_data'), (error, hobbyResult) => {// });this.hobbyResult.forEach(item => {const hobbyBean = {label: item.value,isChecked: this.hobbies.includes(item.value)}this.hobbyBeans.push(hobbyBean);});}build() {Column() {Text(this.title || "兴趣爱好").fontWeight(FontWeight.Bold).alignSelf(ItemAlign.Start).margin({ left: 24, bottom: 12 })List() {ForEach(this.hobbyBeans, (itemHobby: HobbyBean) => {ListItem() {Row() {Text(itemHobby.label).fontSize(16).fontColor("#182431").layoutWeight(1).textAlign(TextAlign.Start).fontWeight(500).margin({ left: 24 })Toggle({ type: ToggleType.Checkbox, isOn: itemHobby.isChecked }).margin({right: 24}).onChange((isCheck) => {itemHobby.isChecked = isCheck;})}}.height(36)}, itemHobby => itemHobby.label)}.margin({top: 6,bottom: 8}).divider({strokeWidth: 0.5,color: "#0D182431"}).listDirection(Axis.Vertical).edgeEffect(EdgeEffect.None).width("100%")// .height(248)Row({space: 20}) {Button("关闭").dialogButtonStyle().onClick(() => {this.controller.close();})Blank().backgroundColor("#F2F2F2").width(1).opacity(1).height(25)Button("保存").dialogButtonStyle().onClick(() => {this.setHobbiesValue(this.hobbyBeans);this.controller.close();})}}.width("93.3%").padding({top: 14,bottom: 16}).borderRadius(32).backgroundColor(Color.White)}
}@Entry
@Component
struct HomePage {@State hobbies: string = '';@State hobbyResult: Array<DataItemType> = [{"value": "FaceBook"},{"value": "Google"},{"value": "Instagram"},{"value": "Twitter"},{"value": "Linkedin"}]private title: string = '常用网站'customDialogController: CustomDialogController = new CustomDialogController({builder: CustomDialogWidget({hobbies: $hobbies,hobbyResult: this.hobbyResult,title: this.title}),alignment: DialogAlignment.Bottom,customStyle: true,offset: { dx: 0,dy: -20 }});build() {Column() {Button('打开自定义弹窗').width('60%').margin({top: 50}).zIndex(999).onClick(()=>{if (this.customDialogController != undefined) {this.customDialogController.open()}})Text(this.hobbies).fontSize(16).padding(24)}.width('100%')}
}
参考:https://gitee.com/harmonyos/codelabs/tree/master/MultipleDialog