前言
本示例介绍如何封装弹窗,以及如何使用这种封装后的弹窗
效果图预览

使用说明
- 进入案例,点击右上角筛选按钮,顶部弹出筛选框,点击一种文件类型进行筛选
- 点击左上角添加按钮,中间弹出新增文件弹框,输入文件名以及选择文件类型,点击确定按钮添加完毕
- 长按列表项出现弹窗,点击删除按钮,中间弹出删除确认框,点击确认按钮删除完毕
- 长按列表项出现弹窗,底部弹出文件详情弹框
实现思路
-
定义弹窗的父布局builder,支持自定义弹窗内容传入,设置弹窗蒙层。
@Builder export function DialogBuilder(param: EncapsulateDialogBuilderParam) { Stack({ alignContent: getAlignment(param.dialogType) }) { Stack() .width('100%') .height('300%') .backgroundColor(0x33000000) .onClick(() => { if (param.isModalClosedByOverlayClick) { param.closeDialog!(); } }) param.builder.builder({ onConfirm: param.onConfirm, closeDialog: param.closeDialog, data: param.data })
}.width('100%') .height('100%') }
-
使用openCustomDialog接口,该接口可支持传入builder。
public static showCustomDialog(param: DialogParam): void { if (!DialogUtil.uiContext) { return; } let promptAction = DialogUtil.uiContext.getPromptAction(); let encapsulateParam: EncapsulateDialogBuilderParam = DialogUtil.transformDialogParamToEncapsulateDialogBuilderParam(param); let compCont = new ComponentContent(DialogUtil.uiContext, wrapBuilder(DialogBuilder), encapsulateParam); // 设置了弹窗id即可将其与弹窗关联起来,后续可凭据弹窗id关闭弹窗 if (param.dialogId) { DialogUtil.compContMap.set(param.dialogId, compCont); } DialogUtil.fillCancelMethod(encapsulateParam, promptAction, compCont, param.dialogId); DialogUtil.fillConfirmMethod(encapsulateParam, promptAction, compCont, param.dialogId); compCont.update(encapsulateParam); let options: promptAction.BaseDialogOptions = DialogUtil.dealSlideToClose(param); promptAction.openCustomDialog(compCont, options); }
-
自定义关闭弹窗回调。
private static fillCancelMethod(param: EncapsulateDialogBuilderParam, promptAction: PromptAction, compCont: ComponentContent, dialogId: string | undefined) { let customCancel = param.closeDialog; let cancelDialog = () => { if (customCancel) { customCancel(); } if (dialogId) { DialogUtil.compContMap.delete(dialogId); } promptAction.closeCustomDialog(compCont); // 关闭弹框之后释放对应的ComponentContent compCont.dispose(); }; param.closeDialog = cancelDialog; }
-
自定义弹窗确认回调。
private static fillConfirmMethod(param: EncapsulateDialogBuilderParam, promptAction: PromptAction, compCont: ComponentContent, dialogId: string | undefined) { let confirm = param.onConfirm; let confirmDialog = (isCloseDialog?: boolean, data?: ESObject) => { if (confirm) { confirm(isCloseDialog, data); } if (isCloseDialog) { if (dialogId) { DialogUtil.compContMap.delete(dialogId); } promptAction.closeCustomDialog(compCont); compCont.dispose(); } }; param.onConfirm = confirmDialog; }
-
自定义弹窗弹出动效。
/**
- 顶部弹出动画
- @param duration 动画时间
- @returns */ static transitionFromUp(duration: number = 200): TransitionEffect { return TransitionEffect.asymmetric( TransitionEffect.OPACITY.animation({ duration: duration }).combine( TransitionEffect.move(TransitionEdge.TOP).animation({ duration: duration })), TransitionEffect.OPACITY.animation({ delay: duration, duration: duration }).combine( TransitionEffect.move(TransitionEdge.TOP).animation({ duration: duration })) ) }
使用步骤
-
初始化DialogUtil,需调用其init方法将UIContext传入。
aboutToAppear(): void { DialogUtil.init(this.getUIContext()); ... }
-
定义弹窗builder,该builder必须有且只有DialogBuilderParam参数。
@Builder export function addFileDialogBuilder(param: DialogBuilderParam) { AddFileComponent({ param: param }) }
-
定义弹窗封装组件,该组件内部必须有DialogBuilderParam参数且使用@Prop注解。
@Component export struct AddFileComponent { @Prop param: DialogBuilderParam; ... }
-
以上就封装好了自定义弹窗,接下来使用只需要调用一下showCustomDialog方法,将对应弹窗封装的builder传入。
showFileInfo(item: FileItem) { // 打开筛选弹窗 DialogUtil.showCustomDialog({ builder: wrapBuilder(fileInfoDialogBuilder), dialogType: DialogTypeEnum.BOTTOM, dialogBuilderParam: { data: item } }) }
如果您想系统深入地学习 HarmonyOS 开发或想考取HarmonyOS认证证书,欢迎加入华为开发者学堂:
请点击→: HarmonyOS官方认证培训
