HarmonyOS 使用SubWindow 创建的全局Loading框 不是调用时立即出现

使用 SubWindow 创建全局Loading 框, 按道理是会拦截点击掉MainWindow的点击事件的。

但是实际测试的时候发现 调用 window.showWindow() , 窗口并没有立即被展现出来。

证明场景是:我们有一个Button, onClick的时候会 调用 window.showWindow(), 但是如果快速点击Button, 按钮响应了两次点击事件。 第二次的点击并没有被 subWindow 拦截掉。

全局Loading框代码如下:

export class CommonLoadingDialog {
  static readonly LOADING_DIALOG_WINDOW_NAME: string = 'sub_window_loading_dialog';

  static showLoading(message: string = '加载中...') {

    let localStorage = LocalStorage.getShared();
    if (!localStorage) {
      localStorage = new LocalStorage();
    }
    localStorage.setOrCreate(CommonLoadingDialog.LOADING_DIALOG_WINDOW_NAME, message);
    let mainWindow: window.WindowStage | undefined = WindowHelper.instance().getWindow();
    if (mainWindow) {
      if (SubWindowManager.getInstance().hasSubWindow(CommonLoadingDialog.LOADING_DIALOG_WINDOW_NAME)) {
        CommonLoadingDialog.hideLoading()
      }
      mainWindow.createSubWindow(CommonLoadingDialog.LOADING_DIALOG_WINDOW_NAME).then(async (window: window.Window) => {
        if (window) {
          SubWindowManager.getInstance().putSubWindow(CommonLoadingDialog.LOADING_DIALOG_WINDOW_NAME, window);
          await window.loadContentByName(EntryUrlConstants.COMMON_LOADING_DIALOG, localStorage);
          await window.resize(WindowHelper.instance().getScreenWidth(), WindowHelper.instance().getScreenHeight());
          window.setWindowBackgroundColor('#00000000'); // 这里给窗口设置遮罩颜色
          Logger.info(`买卖时间   调用show的时间戳 : ${new Date().getTime()}`)
          window.showWindow().then(() => {
            Logger.info(`买卖时间   show回调的时间戳 : ${new Date().getTime()}`)
          });
        }
      })
    }
  }

  static async hideLoading(): Promise<boolean> {
    if (WindowHelper.instance().getWindow()) {
      await SubWindowManager.getInstance().closeSubWindow(CommonLoadingDialog.LOADING_DIALOG_WINDOW_NAME);
    }
    return true;
  }
}
HarmonyOS
2024-12-26 16:11:52
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
Heiang

参考以下demo:

CommonWindow.ets

import window from '@ohos.window';
import common from '@ohos.app.ability.common';
import { BusinessError } from '@ohos.base';
import { entryName } from './MainPage';

export class CommonWindow {
  private storage: LocalStorage | null = null;
  private subWindow: window.Window | null = null;
  private windowStage1: window.WindowStage | null = null
  private context: common.UIAbilityContext | null = null;

  private init() {
    this.context = getContext(this) as common.UIAbilityContext;
    let data: Data = { subWindowStage: null, storage: null };
    this.context.eventHub.emit("createWindow", data);
    this.windowStage1 = data.subWindowStage;
    this.storage = data.storage;
    console.log("aboutToAppear end createWindowStage");
    this.context.eventHub.on("closeWindow", (data: Data) => {
      this.destroySubWindow();
    })
  }

  showWindow() {
    this.init();
    if (this.subWindow) {
      console.log("subWindow is already exist");
      return;
    }
    try {
      if (!this.windowStage1) {
        console.error("this.windowStage1 is null");
        return;
      }
      this.windowStage1.createSubWindow('mySubWindow', (err: BusinessError, data) => {
        const errCode: number = err.code;
        if (errCode) {
          console.error('Failed to create the subWindow. Cause: ' + JSON.stringify(err));
          return;
        }
        this.subWindow = (data as window.Window);
        console.info('Succeeded in creating the subWindow. Data: ' + JSON.stringify(data));
        if (!this.subWindow) {
          console.info('Failed to load the content. Cause: windowClass is null');
        } else {
          let names: Array<'status' | 'navigation'> = [];
          this.subWindow.setWindowSystemBarEnable(names);
          this.subWindow.setWindowTouchable(false); //设置是否可以点击
          this.loadContent(entryName);
          this.showSubWindow();
        }
      });
    } catch (exception) {
      console.error('Failed to create the window. Cause: ' + JSON.stringify(exception));
    }
  }

  private showSubWindow() {
    if (this.subWindow) {
      this.subWindow.showWindow((err: BusinessError) => {
        const errCode: number = err.code;
        if (errCode) {
          console.error('Failed to show the window. Cause: ' + JSON.stringify(err));
          return;
        }
        console.info('Succeeded in showing the window.');
      });
    } else {
      console.info('showSubWindow subWindow not created.');
    }
  }

  destroySubWindow() {
    if (this.subWindow) {
      this.subWindow.destroyWindow((err) => {
        const errCode: number = err.code;
        if (errCode) {
          console.error('Failed to destroy the window. Cause:' + JSON.stringify(err));
          return;
        }
        this.subWindow = null
      });
    } else {
      console.info('showSubWindow subWindow not created.');
    }
  }

  private loadContent(path: string) {
    if (this.subWindow) {
      let that = this;
      let para: Record<string, number> = { 'PropA': 66 };
      that.storage = new LocalStorage(para);
      if (that.storage != null && this.subWindow != null) {
        that.storage.setOrCreate("windowObj", this.subWindow)
      }
      this.subWindow.loadContentByName(path, this.storage, (err: BusinessError) => {
        const errCode: number = err.code;
        if (errCode) {
          return;
        }
        if (this.subWindow) {
          this.subWindow.setWindowBackgroundColor('#cc000e03')
        }
      });
    } else {
      console.info('loadContent subWindow not created.');
    }
  }
}

export interface Data {
  subWindowStage: window.WindowStage | null,
  storage: LocalStorage | null
}

index.ets

import { CommonWindow } from '../uitls/CommonWindow';

@Entry
@Component
struct Index {
  testSubWindowDialog() {
    let window = new CommonWindow()
    window.showWindow();
    setTimeout(() => {
      window.destroySubWindow()
    }, 2000)
  }

  build() {
    Row() {
      Column() {
        Button("子窗口弹窗")
          .margin({ top: 20 })
          .onClick(() => {
            testSubWindowDialog();
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

在EntryAbility中加入:

subWindowStage: window.WindowStage | null = null;
onWindowStageCreate(windowStage: window.WindowStage): void {
  ...
  this.subWindowStage = windowStage;
  const that: EntryAbility = this
  this.context.eventHub.on("createWindow", (data: Data) => {
  if (that.subWindowStage != undefined) {
  data.subWindowStage = that.subWindowStage
}
else {
  hilog.info(0x0000, 'testTag', '%{public}s', 'that.subWindowStage == undefined');
}
})
...

}
分享
微博
QQ
微信
回复
2024-12-26 17:33:57
相关问题
HarmonyOS 全局loading
377浏览 • 1回复 待解决
HarmonyOS 如何在全局使用loading组件?
1150浏览 • 1回复 待解决
HarmonyOS 全局loading组件
730浏览 • 1回复 待解决
HarmonyOS 全局loading实现方案
236浏览 • 1回复 待解决
HarmonyOS 全局loading菊花如何实现?
820浏览 • 1回复 待解决
HarmonyOS 没有全局api loading动画
764浏览 • 1回复 待解决
HarmonyOS 网络请求loading
371浏览 • 1回复 待解决
HarmonyOS 全局loading有什么方案吗
411浏览 • 1回复 待解决
HarmonyOS 是否有全局loading这种控件?
907浏览 • 1回复 待解决
HarmonyOS通过方法调用loading有吗?
803浏览 • 0回复 待解决
HarmonyOS 视频压缩以及请求全局loading
158浏览 • 1回复 待解决
HarmonyOS 如何实现全局
477浏览 • 1回复 待解决
HarmonyOS 应用级全局
721浏览 • 1回复 待解决
HarmonyOS 全局样式怎么创建
637浏览 • 1回复 待解决
HarmonyOS 创建全局弹窗推荐方案
220浏览 • 1回复 待解决
process调用时构建异常
552浏览 • 1回复 待解决