标题概述
鸿蒙自带的自定义弹窗存在不停置顶的标题,详细业务例子
在隐私弹窗的Dialog里通过router跳转到隐私协议内容页后,弹窗不停处于最外层。按照真实业务,应该是在隐私弹窗的上层压入隐私协议,退出隐私协议页面后,弹窗还在。
目前鸿蒙自带的@CustomDialog 以及ComponentContent 封装弹窗类组件两种API实现结果均是弹窗不停置顶
解决方案
目前有两种解决方案
1.子窗口: 通过创建子窗口,并在子窗口Page内加载@Builder自定义组件( 弹窗 ) —— 本文
2.关闭 - 打开:通过订阅openCustomDialog和closeCustomDialog事件来控制显隐,实现业务。
详细实现
工程结构
- LoadContentWindow.ets // 子窗口
- SubWindowParams.ets // 子窗口传参封装
- SubWindowApi.ets // 子窗口创建初始化封装
- SubWindowFunction.ets // 方法调用封装
1. 子窗口的创建初始化,以及烧毁,并且订阅对应事件 - SubWindowApi.ets
- const EVENT_ID = 1234565; // 持续订阅事件ID
- // window实例
- interface Handler {
- windowStage: window.WindowStage;
- }
- /**
- * 窗口的创建,加载,显示,销毁操作
- */
- export class SubWindowApi {
- private subWindow: window.Window | null = null; // 初始化window实例
- private Storage: LocalStorage = new LocalStorage(); // 创建页面级UI状态存储对象
- // eventId为1234565的持续订阅的事件
- private callbackEvent: emitter.InnerEvent = {
- eventId: EVENT_ID
- }
- // 显示当前窗口
- private showSubWindow() {
- if (this.subWindow) {
- this.subWindow.showWindow((err: BusinessError) => {
- if (err.code) {
- console.error('Fail to show window, Cause: ' + JSON.stringify(err));
- }
- })
- }
- }
- // 为当前WindowStage加载命名路由页面
- private loadContent(path: string) {
- if (this.subWindow) {
- // 用loadContentByName为当前窗口加载命名路由页面,通过LocalStorage传递状态属性给加载的页面
- this.subWindow.loadContentByName(path, this.Storage, (err: BusinessError) => {
- if (err.code) {
- console.error("Failed to load the content. Cause:" + JSON.stringify(err));
- return;
- }
- });
- }
- }
- // 销毁当前窗口
- private destroySubWindow() {
- if (this.subWindow) {
- this.subWindow.destroyWindow((err) => {
- if (err.code) {
- console.error('Fail to destroy the window. Cause:' + JSON.stringify(err));
- return;
- }
- this.subWindow = null;
- });
- }
- }
- // 创建子窗口
- private createSubWindow(windowStage: window.WindowStage | null) {
- try {
- if (!windowStage) {
- return;
- }
- windowStage.createSubWindow('subDialogWindow', (err: BusinessError, data) => {
- if (err.code) {
- console.error("Failed to create the subwindow, Cause: " + JSON.stringify(err));
- return;
- }
- this.subWindow = (data as window.Window);
- if (this.subWindow) {
- // 设置子窗口尺寸
- this.subWindow.resize(
- UIUtil.getScreenWidthPx(),
- UIUtil.getScreenHeightPx())
- // 布局避让状态栏与导航栏
- this.subWindow.setWindowLayoutFullScreen(false)
- // 设置子窗口可触
- this.subWindow.setWindowTouchable(true);
- // 设置窗口UI
- this.loadContent(entryName);
- // 展示子窗口
- this.showSubWindow();
- }
- });
- } catch (exception) {
- console.error("Failed to create the window, Cause: " + JSON.stringify(exception));
- }
- }
- /**
- * 订阅eventId为1234565的事件
- */
- subscribeCallback(): void {
- emitter.on(this.callbackEvent, () => {
- this.hideSubWindow();
- })
- }
- /**
- * 取消针对eventId为1234565的事件的订阅
- */
- offCallback(): void {
- emitter.off(this.callbackEvent.eventId);
- }
- /**
- * 更新key为'ad'的变量值
- * @param { AdWindowParams } params - 页面显示的值
- */
- updateOrCreateParams(params: SubWindowParams): void {
- this.Storage.setOrCreate("subWindowParams", params);
- }
- /**
- * 创建并展示弹窗
- * @param { AdWindowParams } params - 页面显示的值
- * @param { Handler } handler - WindowStage对象
- */
- initSubWindow(handler: Handler, params: SubWindowParams): void {
- const windowStage = handler.windowStage;
- // 注册回调
- this.subscribeCallback();
- // 初始化参数
- this.updateOrCreateParams(params);
- // 新建子窗口
- this.createSubWindow(windowStage);
- }
- /**
- * 隐藏弹窗
- */
- hideSubWindow(): void {
- // 注销监听事件
- this.offCallback();
- // 关闭弹窗
- this.destroySubWindow();
- }
- }
复制代码 2. 创建子窗口所加载的页面 - LoadContentWindow.ets
- export const entryName: string = 'LoadContent';
- const EVENT_ID = 1234565; // 持续订阅事件ID
- const DURATION = 400; // 动画时间
- const IMAGE_SCALE = 0.8; // 弹窗画面缩放大小
- @Entry({
- routeName: entryName,
- storage: LocalStorage.getShared()
- })
- // window单独加载的命名路由页面: LoadContent
- @Component
- export struct LoadContent {
- @LocalStorageLink('subWindowParams') params: SubWindowParams | null = null;
- private windowClass: window.Window = window.findWindow('subDialogWindow');
- private event: emitter.InnerEvent = {
- eventId: EVENT_ID
- }
- aboutToAppear(): void {
- if (this.params != null) {
- this.params.onBtnCloseListener = () => {
- // 触发回调,关闭弹窗
- emitter.emit(this.event);
- }
- }
- }
- onBackPress(): boolean | void {
- //监听反回键
- emitter.emit(this.event);
- return true;
- }
- onPageHide(): void {
- //设置子窗口蒙层颜色
- try {
- this.windowClass.setWindowBackgroundColor('#ffffff');
- } catch (exception) {
- console.error('Failed to set the background color. Cause: ' + JSON.stringify(exception));
- }
- }
- onPageShow(): void {
- //设置子窗口蒙层颜色
- try {
- this.windowClass.setWindowBackgroundColor("#57050505")
- } catch (exception) {
- console.error('Failed to set the background color. Cause: ' + JSON.stringify(exception));
- }
- }
- build() {
- Column() {
- Stack() {
- if (this.params != null) {
- dialog_privacy(this.params)
- } else {
- Text("NULL")
- }
- }
- }
- .width(UIUtil.getScreenWidthVp())
- .height(UIUtil.getScreenHeightVp())
- .alignItems(HorizontalAlign.Center)
- .justifyContent(FlexAlign.Center)
- .transition(TransitionEffect.OPACITY.animation({
- duration: DURATION,
- curve: Curve.Ease
- }).combine(TransitionEffect.scale({
- x: IMAGE_SCALE,
- y: IMAGE_SCALE
- })))
- }
- }
复制代码 3. 封装方法调用 - SubWindowFunction.ets
- const context = getContext(this) as common.UIAbilityContext; // 获取当前页面的上下文
- /**
- * 创建并展示弹窗
- * @param { api.SubWindowApi | null } SubWindowApi - SubWindowApi对象
- * @param { window.WindowStage | undefined } windowStage - WindowStage对象
- */
- export function showApiSubWindow(SubWindowApi: api.SubWindowApi | null, windowStage: window.WindowStage | undefined, params: SubWindowParams) {
- SubWindowApi?.initSubWindow({ windowStage: windowStage as window.WindowStage }, params);
- }
- /**
- * 隐藏弹窗
- * @param { api.SubWindowApi | null } SubWindowApi - SubWindowApi对象
- */
- export function hideApiSubWindow(SubWindowApi: api.SubWindowApi | null) {
- SubWindowApi?.hideSubWindow();
- }
复制代码 4. 自定义传参 - SubWindowParams.ets
- export class SubWindowParams {
- onBtnCloseListener?: () => void
-
- constructor() {
- }
- }
复制代码 参考
https://gitee.com/harmonyos-cases/cases/blob/master/CommonAppDevelopment/feature/customdialog/README.md
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |