ArkTS全局UI自定义弹窗的替代办法——子窗口

目录

前言

问题

方案

一、创建子窗口

二、加载子窗口目标页面

三、销毁子窗口


前言

最近在学习窗口的时候想起来之前的一个问题,如何实现一个全局的倒计时弹窗,监听触摸事件,可以在任何页面展示并自动关闭。

问题

在Openharmony4.1 api11版本@ohos.promptAction模块中提供了打开和关闭自定义弹窗的方法:openCustomDialog11+以及closeCustomDialog11+

CustomDialogOptions提供了CustomBuilder参数可以结合@Builder生成用户希望的自定义组件。

但是相应在api10中只提供了showDialog方法弹窗选项,有以下问题:

1. 自定义弹窗选项很少,只可以改变内容文本、标题文本,无法自定义样式,无法加入倒计时。

2. 打开的dialog需要手动点击才可以关闭,不会随页面跳转消失。

方案

学习窗口之后,发现@window提供了createSubWindow接口创建应用子窗口,可以改变其大小、位置、窗口背景色等属性;通过setUIContent和showWindow接口加载显示子窗口的具体内容;同时可根据具体实现逻辑,使用destroyWindow接口销毁子窗口。这样完美解决了使用showdialog产生的问题。

先来看看官网介绍子窗口的使用。

import UIAbility from '@ohos.app.ability.UIAbility';

let windowStage_ = null;
let sub_windowClass = null;
export default class EntryAbility extends UIAbility {
    showSubWindow() {
        // 1.创建应用子窗口。
        windowStage_.createSubWindow("mySubWindow", (err, data) => {
            if (err.code) {
                console.error('Failed to create the subwindow. Cause: ' + JSON.stringify(err));
                return;
            }
            sub_windowClass = data;
            console.info('Succeeded in creating the subwindow. Data: ' + JSON.stringify(data));
            // 2.子窗口创建成功后,设置子窗口的位置、大小及相关属性等。
            // 第一个参数窗口在x轴方向移动的值,单位为px
            // 第二个参数窗口在y轴方向移动的值,单位为px
            sub_windowClass.moveWindowTo(300, 300, (err) => {
                if (err.code) {
                    console.error('Failed to move the window. Cause:' + JSON.stringify(err));
                    return;
                }
                console.info('Succeeded in moving the window.');
            });
            // 第一个参数目标窗口的宽度,单位为px;
            // 第二个参数目标窗口的高度,单位为px;
            sub_windowClass.resize(500, 500, (err) => {
                if (err.code) {
                    console.error('Failed to change the window size. Cause:' + JSON.stringify(err));
                    return;
                }
                console.info('Succeeded in changing the window size.');
            });
            // 3.为子窗口加载对应的目标页面。
            sub_windowClass.setUIContent("pages/page3", (err) => {
                if (err.code) {
                    console.error('Failed to load the content. Cause:' + JSON.stringify(err));
                    return;
                }
                console.info('Succeeded in loading the content.');
                // 3.显示子窗口。
                sub_windowClass.showWindow((err) => {
                    if (err.code) {
                        console.error('Failed to show the window. Cause: ' + JSON.stringify(err));
                        return;
                    }
                    console.info('Succeeded in showing the window.');
                });
            });
        })
    }

    destroySubWindow() {
        // 4.销毁子窗口。当不再需要子窗口时,可根据具体实现逻辑,使用destroy对其进行销毁。
        sub_windowClass.destroyWindow((err) => {
            if (err.code) {
                console.error('Failed to destroy the window. Cause: ' + JSON.stringify(err));
                return;
            }
            console.info('Succeeded in destroying the window.');
        });
    }

    onWindowStageCreate(windowStage) {
        windowStage_ = windowStage;
        // 开发者可以在适当的时机,如主窗口上按钮点击事件等,创建子窗口。并不一定需要在onWindowStageCreate调用,这里仅作展示
        this.showSubWindow();
    }

    onWindowStageDestroy() {
        // 开发者可以在适当的时机,如子窗口上点击关闭按钮等,销毁子窗口。并不一定需要在onWindowStageDestroy调用,这里仅作展示
        this.destroySubWindow();
    }
};

于是我们仿照官方示例,加入到我们的代码中。

一、创建子窗口

在我们希望拉起子窗口的地方中加入showSubWindow方法,此时我们的windowStage_还没有初始化,所以我们要获取当前主窗口的窗口管理器,找到当前Ability(如EntryAbility.ts)的onWindowStageCreate(),我们通过AppStorage来传递windowStage,AppStorage支持应用的主线程内多个UIAbility实例间的状态共享。

onWindowStageCreate(windowStage: window.WindowStage) {
    ···
    AppStorage.setOrCreate('windowStage_', windowStage);
    ···
}

二、加载子窗口目标页面

替换示例中setUIContent中的'pages/page3'为自定义页面。

三、销毁子窗口

接下来在我们希望关闭子窗口的地方加入destroySubWindow方法,这时需要sub_windowClass,即拉起子窗口时创建的子窗口对象,这个对象我们可以在showSubWindowwindowStage_.createSubWindow方法的回调函数中获取。同样我们可以通过AppStorage进行传递。

(AppStorage.get('windowStage_') as window.WindowStage).createSubWindow("mySubWindow", (err: BusinessError, data) => {
        let errCode: number = err.code;
        if (errCode) {
          console.error('Failed to create the subwindow. Cause: ' + JSON.stringify(err));
          return;
        }
        AppStorage.setOrCreate('sub_windowClass', data);
})

  • 14
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值