管理应用窗口(Stage模型)

基本概念

  • 窗口沉浸式能力:指对状态栏、导航栏等系统窗口进行控制,减少状态栏导航栏等系统界面的突兀感,从而使用户获得最佳体验的能力。

    沉浸式能力只在应用主窗口作为全屏窗口时生效。通常情况下,应用子窗口(弹窗、悬浮窗口等辅助窗口)和处于自由窗口下的应用主窗口无法使用沉浸式能力。

  • 悬浮窗:全局悬浮窗口是一种特殊的应用窗口,具备在应用主窗口和对应Ability退至后台后仍然可以在前台显示的能力。

    悬浮窗口可以用于应用退至后台后,使用小窗继续播放视频,或者为特定的应用创建悬浮球等快速入口。应用在创建悬浮窗口前,需要申请对应的权限。

场景介绍

在Stage模型下,管理应用窗口的典型场景有:

  • 设置应用主窗口属性及目标页面

  • 设置应用子窗口属性及目标页面

  • 体验窗口沉浸式能力

  • 设置悬浮窗

  • 监听窗口不可交互与可交互事件

以下分别介绍具体开发方式。

接口说明

上述场景涉及的常用接口如下表所示。更多API说明请参见API参考。

实例名 接口名 描述
WindowStage getMainWindow(callback: AsyncCallback): void

获取WindowStage实例下的主窗口。

此接口仅可在Stage模型下使用。

WindowStage loadContent(path: string, callback: AsyncCallback): void

为当前WindowStage的主窗口加载具体页面。

其中path为要加载到窗口中的页面内容的路径,该路径需添加到工程的main_pages.json文件中。

此接口仅可在Stage模型下使用。

WindowStage createSubWindow(name: string, callback: AsyncCallback): void

创建子窗口。

此接口仅可在Stage模型下使用。

WindowStage on(type: 'windowStageEvent', callback: Callback): void

开启WindowStage生命周期变化的监听。

此接口仅可在Stage模型下使用。

window静态方法 createWindow(config: Configuration, callback: AsyncCallback): void

创建子窗口或者系统窗口。

-config:创建窗口时的参数。

Window setUIContent(path: string, callback: AsyncCallback): void

根据当前工程中某个页面的路径为窗口加载具体的页面内容。

其中path为要加载到窗口中的页面内容的路径,在Stage模型下该路径需添加到工程的main_pages.json文件中。

Window setWindowBrightness(brightness: number, callback: AsyncCallback): void 设置屏幕亮度值。
Window setWindowTouchable(isTouchable: boolean, callback: AsyncCallback): void 设置窗口是否为可触状态。
Window moveWindowTo(x: number, y: number, callback: AsyncCallback): void 移动当前窗口位置。
Window resize(width: number, height: number, callback: AsyncCallback): void 改变当前窗口大小。
Window setWindowLayoutFullScreen(isLayoutFullScreen: boolean): Promise 设置窗口布局是否为全屏布局。
Window setWindowSystemBarEnable(names: Array<'status'|'navigation'>): Promise 设置导航栏、状态栏是否显示。
Window setWindowSystemBarProperties(systemBarProperties: SystemBarProperties): Promise

设置窗口内导航栏、状态栏属性。

systemBarProperties:导航栏、状态栏的属性集合。

Window showWindow(callback: AsyncCallback): void 显示当前窗口。
Window on(type: 'touchOutside', callback: Callback): void 开启本窗口区域外的点击事件的监听。
Window destroyWindow(callback: AsyncCallback): void 销毁当前窗口。

设置应用主窗口

在Stage模型下,应用主窗口由UIAbility创建并维护生命周期。在UIAbility的onWindowStageCreate回调中,通过WindowStage获取应用主窗口,即可对其进行属性设置等操作。还可以在应用配置文件中设置应用主窗口的属性,如最大窗口宽度maxWindowWidth等,详见module.json5配置文件中的abilities标签。

开发步骤

  1. 获取应用主窗口。

    通过getMainWindow接口获取应用主窗口。

  2. 设置主窗口属性。

    可设置主窗口的背景色、亮度值、是否可触等多个属性,开发者可根据需要选择对应的接口。本示例以设置“是否可触”属性为例。

  3. 为主窗口加载对应的目标页面。

    通过loadContent接口加载主窗口的目标页面。

 
  
  1. import { UIAbility } from '@kit.AbilityKit';
  2. import { window } from '@kit.ArkUI';
  3. import { BusinessError } from '@kit.BasicServicesKit';
  4. export default class EntryAbility extends UIAbility {
  5. onWindowStageCreate(windowStage: window.WindowStage) {
  6. // 1.获取应用主窗口。
  7. let windowClass: window.Window | null = null;
  8. windowStage.getMainWindow((err: BusinessError, data) => {
  9. let errCode: number = err.code;
  10. if (errCode) {
  11. console.error(`Failed to obtain the main window. CCode:${err.code}, message:${err.message}`);
  12. return;
  13. }
  14. windowClass = data;
  15. console.info(`Succeeded in obtaining the main window. Result:${data}`);
  16. // 2.设置主窗口属性。以设置"是否可触"属性为例。
  17. let isTouchable: boolean = true;
  18. windowClass.setWindowTouchable(isTouchable, (err: BusinessError) => {
  19. let errCode: number = err.code;
  20. if (errCode) {
  21. console.error('Failed to set the window to be touchable. Cause:' + JSON.stringify(err));
  22. return;
  23. }
  24. console.info('Succeeded in setting the window to be touchable.');
  25. })
  26. })
  27. // 3.为主窗口加载对应的目标页面。
  28. windowStage.loadContent("pages/page2", (err: BusinessError) => {
  29. let errCode: number = err.code;
  30. if (errCode) {
  31. console.error('Failed to load the content. Cause:' + JSON.stringify(err));
  32. return;
  33. }
  34. console.info('Succeeded in loading the content.');
  35. });
  36. }
  37. };

设置应用子窗口

开发者可以按需创建应用子窗口,如弹窗等,并对其进行属性设置等操作。

说明

由于以下几种情况,移动设备场景下不推荐使用子窗口,优先推荐使用控件overlay能力实现。

  • 移动设备场景下子窗不能超出主窗口范围,与控件一致。
  • 分屏窗口与自由窗口模式下,主窗口位置大小发生改变时控件实时跟随变化能力优于子窗。
  • 部分设备平台下根据实际的系统配置限制,子窗只有系统默认的动效和圆角阴影,应用无法设置,自由度低。

开发步骤

  1. 创建应用子窗口。

    通过createSubWindow接口创建应用子窗口。

  2. 设置子窗口属性。

    子窗口创建成功后,可以改变其大小、位置等,还可以根据应用需要设置窗口背景色、亮度等属性。

  3. 加载显示子窗口的具体内容。

    通过setUIContent和showWindow接口加载显示子窗口的具体内容。

  4. 销毁子窗口。

    当不再需要某些子窗口时,可根据具体实现逻辑,使用destroyWindow接口销毁子窗口。

直接在onWindowStageCreate里面创建子窗口的整体示例代码如下:

 
  
  1. import { UIAbility } from '@kit.AbilityKit';
  2. import { window } from '@kit.ArkUI';
  3. import { BusinessError } from '@kit.BasicServicesKit';
  4. let windowStage_: window.WindowStage | null = null;
  5. let sub_windowClass: window.Window | null = null;
  6. export default class EntryAbility extends UIAbility {
  7. showSubWindow() {
  8. // 1.创建应用子窗口。
  9. if (windowStage_ == null) {
  10. console.error('Failed to create the subwindow. Cause: windowStage_ is null');
  11. }
  12. else {
  13. windowStage_.createSubWindow("mySubWindow", (err: BusinessError, data) => {
  14. let errCode: number = err.code;
  15. if (errCode) {
  16. console.error('Failed to create the subwindow. Cause: ' + JSON.stringify(err));
  17. return;
  18. }
  19. sub_windowClass = data;
  20. console.info('Succeeded in creating the subwindow. Data: ' + JSON.stringify(data));
  21. // 2.子窗口创建成功后,设置子窗口的位置、大小及相关属性等。
  22. sub_windowClass.moveWindowTo(300, 300, (err: BusinessError) => {
  23. let errCode: number = err.code;
  24. if (errCode) {
  25. console.error('Failed to move the window. Cause:' + JSON.stringify(err));
  26. return;
  27. }
  28. console.info('Succeeded in moving the window.');
  29. });
  30. sub_windowClass.resize(500, 500, (err: BusinessError) => {
  31. let errCode: number = err.code;
  32. if (errCode) {
  33. console.error('Failed to change the window size. Cause:' + JSON.stringify(err));
  34. return;
  35. }
  36. console.info('Succeeded in changing the window size.');
  37. });
  38. // 3.为子窗口加载对应的目标页面。
  39. sub_windowClass.setUIContent("pages/page3", (err: BusinessError) => {
  40. let errCode: number = err.code;
  41. if (errCode) {
  42. console.error('Failed to load the content. Cause:' + JSON.stringify(err));
  43. return;
  44. }
  45. console.info('Succeeded in loading the content.');
  46. // 3.显示子窗口。
  47. (sub_windowClass as window.Window).showWindow((err: BusinessError) => {
  48. let errCode: number = err.code;
  49. if (errCode) {
  50. console.error('Failed to show the window. Cause: ' + JSON.stringify(err));
  51. return;
  52. }
  53. console.info('Succeeded in showing the window.');
  54. });
  55. });
  56. })
  57. }
  58. }
  59. destroySubWindow() {
  60. // 4.销毁子窗口。当不再需要子窗口时,可根据具体实现逻辑,使用destroy对其进行销毁。
  61. (sub_windowClass as window.Window).destroyWindow((err: BusinessError) => {
  62. let errCode: number = err.code;
  63. if (errCode) {
  64. console.error('Failed to destroy the window. Cause: ' + JSON.stringify(err));
  65. return;
  66. }
  67. console.info('Succeeded in destroying the window.');
  68. });
  69. }
  70. onWindowStageCreate(windowStage: window.WindowStage) {
  71. windowStage_ = windowStage;
  72. // 开发者可以在适当的时机,如主窗口上按钮点击事件等,创建子窗口。并不一定需要在onWindowStageCreate调用,这里仅作展示
  73. this.showSubWindow();
  74. }
  75. onWindowStageDestroy() {
  76. // 开发者可以在适当的时机,如子窗口上点击关闭按钮等,销毁子窗口。并不一定需要在onWindowStageDestroy调用,这里仅作展示
  77. this.destroySubWindow();
  78. }
  79. };

你可能感兴趣的:(ArkUI,microsoft,前端,服务器)