HarmonyOS 鸿蒙Next中如何创建一个不会被应用内任何页面和窗口遮盖的Dialog
HarmonyOS 鸿蒙Next中如何创建一个不会被应用内任何页面和窗口遮盖的Dialog 目前我的App内存在这样的逻辑:
启动Ability后,内部主窗口自动打开了我指向的Page,这时候我在这个Page内打开一个弹框,我希望的是这个弹框是比较重要的,需要用户响应结束后才能继续操作App。但是这时候Page内还有其他逻辑正在运行,他可能会打开一个新的Window(通过的方式创建子窗口),子窗口内也有自己的Page和UI逻辑,而这时候这个子窗口就把根窗口打开的那个Dialog覆盖掉了。
我还查看了这个API文档中提到的,其中有个showInSubWindows配置,似乎是可以把Dialog作为一个独立的Window,估计这个用法适用于dialog是最后打开的,Window就是后打开的在最上面。 但是我的逻辑是希望Dialog是单独一层,显示在所有Window之上,即使后面再开新的Window,也不会遮盖先打开的这个Dialog。
请问大佬们有没有知道解决方案的呢?
更多关于HarmonyOS 鸿蒙Next中如何创建一个不会被应用内任何页面和窗口遮盖的Dialog的实战教程也可以访问 https://www.itying.com/category-93-b0.html
【背景知识】
- 通过WindowStage下的createSubWindow方法可以创建子窗口。
【解决方案】
目前规格上不支持,弹窗所在的窗口取决于自身锚点的UI上下文,它所属的窗口是在打开时确定的,它通过主窗口页面的点击操作唤起,因此锚点在主窗口上,其层级也就高于主窗口页面而低于子窗口。
更多关于HarmonyOS 鸿蒙Next中如何创建一个不会被应用内任何页面和窗口遮盖的Dialog的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
可以使用子窗口模式
import { window } from '@kit.ArkUI';
let dialogWindow: window.Window;
async function createDialogWindow() {
const context = this as common.UIAbilityContext;
// 创建子窗口参数
const config: window.WindowTypeOptions = {
name: 'dialogWindow',
windowType: window.WindowType.TYPE_APP_DIALOG,
ctx: context
};
// 创建并显示窗口
dialogWindow = await window.createWindow(context, config);
dialogWindow.moveTo(0, 0).then(() => {
dialogWindow.resize(display.getDefaultDisplaySync().width, display.getDefaultDisplaySync().height);
dialogWindow.loadContent('pages/DialogPage');
});
}
通过createSubWindow创建独立子窗口承载弹窗,利用窗口系统自动管理Z轴顺序的特性,后续创建的子窗口默认会覆盖之前的窗口。
强制弹窗窗口置顶可以结合showInSubWindow参数与窗口生命周期管理,来确保弹窗窗口始终保持最高层级。
主要步骤----------
- 创建独立弹窗子窗口
let dialogWindow: window.WindowClass | null = null;
// 创建专用弹窗子窗口
context.windowStage.createSubWindow('globalDialog', (err, windowClass) => {
if (err.code) return;
dialogWindow = windowClass;
windowClass.setWindowLayoutFullScreen(true); // 全屏布局避免遮挡
windowClass.setUIContent("pages/GlobalDialogPage"); // 弹窗内容页
});
- 设置弹窗窗口属性
dialogWindow.on('windowStageEvent', (event) => {
if (event.type === window.WindowStageEventType.SHOW) {
// 禁止手势穿透
dialogWindow.setTouchable(true);
// 设置窗口置顶标志位
dialogWindow.setWindowProperties({
zOrder: window.ZOrder.ALWAYS_ON_TOP
});
}
});
- 通过API触发弹窗显示
promptAction.showDialog({
title: '重要提示',
message: '请先处理当前操作',
showInSubWindow: true, // 参数[原题链接]
buttons: [{ text: '确认' }]
}, (err, result) => {
if (result.index === 0) {
dialogWindow.destroy();
}
});
在HarmonyOS Next中,要创建置顶Dialog需使用WindowManager
。通过WindowStage
获取WindowManager
实例,设置WindowType.TYPE_SYSTEM_ALERT
窗口类型,并配置FLAG_NOT_TOUCH_MODAL
和FLAG_NOT_FOCUSABLE
标志。关键代码示例:
let windowManager = windowStage.getWindowManager()
let dialogWindow = await windowManager.createWindow("dialog", WindowType.TYPE_SYSTEM_ALERT)
dialogWindow.setWindowFlags(WindowFlag.FLAG_NOT_TOUCH_MODAL | WindowFlag.FLAG_NOT_FOCUSABLE)
需在module.json5
中声明ohos.permission.SYSTEM_FLOAT_WINDOW
权限。
在HarmonyOS Next中要实现始终置顶的Dialog,可以使用WindowStage的showDialogForSystem方法。这个方法创建的Dialog会显示在系统级别,不会被应用内其他窗口覆盖。具体实现步骤如下:
- 获取当前WindowStage实例:
let windowStage = this.context.windowStage;
- 使用showDialogForSystem方法创建系统级Dialog:
windowStage.showDialogForSystem({
title: '重要提示',
message: '请先处理此弹窗',
buttons: [
{
text: '确定',
color: '#FF0000',
action: () => {
// 确定按钮回调
}
}
]
});
这种方法创建的Dialog会显示在所有应用窗口之上,包括后续通过createSubWindow创建的子窗口。需要注意的是,系统级Dialog的样式和交互方式可能会有一些限制,建议参考官方文档进行样式调整。
如果需要对Dialog有更多自定义需求,也可以考虑创建一个全屏透明的Window,在这个Window中实现自定义Dialog效果,这样也能保证不会被其他窗口覆盖。