diff --git a/zh-cn/application-dev/ability/stage-ability.md b/zh-cn/application-dev/ability/stage-ability.md index fc43d7b00c5d1a68fa67c98bd5988c65cb4bb001..061faac68db96402e30ad0cf89b1d1136c9c5660 100644 --- a/zh-cn/application-dev/ability/stage-ability.md +++ b/zh-cn/application-dev/ability/stage-ability.md @@ -72,7 +72,7 @@ Ability功能如下(Ability类,具体的API详见[接口文档](../reference ``` 4. 实现Ability生命周期接口。 - 在`onWindowStageCreate(windowStage)`中通过loadContent接口设置应用要加载的页面,window接口的使用详见[窗口开发指导](../windowmanager/window-guidelines.md)。 + 在`onWindowStageCreate(windowStage)`中通过loadContent接口设置应用要加载的页面,window接口的使用详见[窗口开发指导](../windowmanager/application-window-stage.md)。 ```ts export default class MainAbility extends Ability { onCreate(want, launchParam) { diff --git a/zh-cn/application-dev/website.md b/zh-cn/application-dev/website.md index 55e05a3ce83919b8c7ce203b0478d909445a93fc..cf096c29978b1941bc14cbbc7441be311b18d01e 100644 --- a/zh-cn/application-dev/website.md +++ b/zh-cn/application-dev/website.md @@ -190,7 +190,9 @@ - 窗口管理 - 窗口 - [窗口开发概述](windowmanager/window-overview.md) - - [窗口开发指导](windowmanager/window-guidelines.md) + - [管理应用窗口(Stage模型)](windowmanager/application-window-stage.md) + - [管理应用窗口(FA模型)](windowmanager/application-window-fa.md) + - [管理系统窗口(仅Stage模型支持)](windowmanager/system-window-stage.md) - 屏幕属性 - [屏幕属性开发概述](windowmanager/display-overview.md) - [屏幕属性开发指导](windowmanager/display-guidelines.md) diff --git a/zh-cn/application-dev/windowmanager/Readme-CN.md b/zh-cn/application-dev/windowmanager/Readme-CN.md index fcfb79f31d426720360b787f9efba03f1be16849..fff76b863d6b9198dec861f7cffaf7e9025009d2 100644 --- a/zh-cn/application-dev/windowmanager/Readme-CN.md +++ b/zh-cn/application-dev/windowmanager/Readme-CN.md @@ -1,12 +1,16 @@ # 窗口管理 -* 窗口 - * [窗口开发概述](window-overview.md) - * [窗口开发指导](window-guidelines.md) -* 屏幕属性 - * [屏幕属性开发概述](display-overview.md) - * [屏幕属性开发指导](display-guidelines.md) -* 屏幕截图 - * [屏幕截图开发概述](screenshot-overview.md) - * [屏幕截图开发指导](screenshot-guidelines.md) +- 窗口 + - [窗口开发概述](window-overview.md) + - [管理应用窗口(Stage模型)](application-window-stage.md) + - [管理应用窗口(FA模型)](application-window-fa.md) + - [管理系统窗口(仅Stage模型支持)](system-window-stage.md) + +- 屏幕属性 + - [屏幕属性开发概述](display-overview.md) + - [屏幕属性开发指导](display-guidelines.md) + +- 屏幕截图 + - [屏幕截图开发概述](screenshot-overview.md) + - [屏幕截图开发指导](screenshot-guidelines.md) \ No newline at end of file diff --git a/zh-cn/application-dev/windowmanager/application-window-fa.md b/zh-cn/application-dev/windowmanager/application-window-fa.md new file mode 100644 index 0000000000000000000000000000000000000000..c8128dfdc707cd4a2dcf0a8123ec4c2a5cbe6cb3 --- /dev/null +++ b/zh-cn/application-dev/windowmanager/application-window-fa.md @@ -0,0 +1,254 @@ +# 管理应用窗口(FA模型) + +## 基本概念 + +窗口沉浸式能力:指对状态栏、导航栏等系统窗口进行控制,减少状态栏导航栏等系统界面的突兀感,从而使用户获得最佳体验的能力。 + +沉浸式能力只在应用主窗口作为全屏窗口时生效。通常情况下,应用子窗口(弹窗、悬浮窗口等辅助窗口)和处于自由窗口下的应用主窗口无法使用沉浸式能力。 + +## 场景介绍 + +在FA模型下,管理应用窗口的典型场景有: + +- 设置应用子窗口属性及目标页面 + +- 体验窗口沉浸式能力 + +以下分别介绍具体开发方式。 + + +## 接口说明 + +上述场景涉及的常用接口如下表所示。更多API说明请参见[API参考](../reference/apis/js-apis-window.md)。 + +| 实例名 | 接口名 | 描述 | +| -------- | -------- | -------- | +| window静态方法 | create(id:string,type:WindowType,callback:AsyncCallback]<Window>):void | 创建子窗口。
此接口仅可在`FA`模型下使用。 | +| window静态方法 | getTopWindow(callback:AsyncCallback<Window>):void | 获取当前应用内最后显示的窗口。
此接口仅可在`FA`模型下使用。 | +| window静态方法 | find(id:string,callback:AsyncCallback<Window>):void | 查找`id`所对应的窗口。 | +| Window | loadContent(path:string,callback:AsyncCallback<void>):void | 为当前窗口加载具体页面内容。 | +| Window | moveTo(x:number,y:number,callback:AsyncCallback<void>):void | 移动当前窗口。 | +| Window | setBackgroundColor(color:string,callback:AsyncCallback<void>):void | 设置窗口的背景色 | +| Window | setBrightness(brightness:number,callback:AsyncCallback<void>):void | 设置屏幕亮度值。 | +| Window | resetSize(width:number,height:number,callback:AsyncCallback<void>):void | 改变当前窗口大小。 | +| Window | setFullScreen(isFullScreen:boolean,callback:AsyncCallback<void>):void | 设置窗口是否全屏显示。 | +| Window | setLayoutFullScreen(isLayoutFullScreen:boolean,callback:AsyncCallback<void>):void | 设置窗口布局是否为全屏布局。 | +| Window | setSystemBarEnable(names:Array<'status'\|'navigation'>):Promise<void> | 设置导航栏、状态栏是否显示。 | +| Window | setSystemBarProperties(systemBarProperties:SystemBarProperties,callback:AsyncCallback<void>):void | 设置窗口内导航栏、状态栏属性。
`systemBarProperties`:导航栏、状态栏的属性集合。 | +| Window | show(callback: AsyncCallback\): void | 显示当前窗口。 | +| Window | on(type:'touchOutside',callback:Callback<void>):void | 开启本窗口区域外的点击事件的监听。 | +| Window | destroy(callback: AsyncCallback<void>):void | 销毁当前窗口。 | + + +## 设置应用子窗口 + +开发者可以按需创建应用子窗口,如弹窗等,并对其进行属性设置等操作。 + + +### 开发步骤 + +1. 创建/获取子窗口对象。 + - 可以通过`window.create`接口创建子窗口。 + - 可以通过`window.getTopWindow`来获取最后显示的窗口得到子窗口。 + - 也可以通过`window.find`接口来查找已经创建的窗口从而得到子窗口。 + + ```js + import window from '@ohos.window'; + + var windowClass = null; + // 1.方式一:创建子窗口。 + window.create("subWindow", window.WindowType.TYPE_APP, (err, data) => { + if (err.code) { + console.error('Failed to create the subWindow. Cause: ' + JSON.stringify(err)); + return; + } + console.info('Succeeded in creating subWindow. Data: ' + JSON.stringify(data)); + windowClass = data; + }); + // 1.方式二:获取子窗口。 + window.getTopWindow((err, data) => { + if (err.code) { + console.error('Failed to get the subWindow. Cause: ' + JSON.stringify(err)); + return; + } + console.info('Succeeded in getting subWindow. Data: ' + JSON.stringify(data)); + windowClass = data; + }); + // 1.方式三:查找得到子窗口。 + window.find("subWindow", (err, data) => { + if (err.code) { + console.error('Failed to find the subWindow. Cause: ' + JSON.stringify(err)); + return; + } + console.info('Succeeded in finding subWindow. Data: ' + JSON.stringify(data)); + windowClass = data; + }); + ``` + +2. 设置子窗口属性。 + 子窗口创建成功后,可以改变其大小、位置等,还可以根据应用需要设置窗口背景色、亮度等属性。 + + + ```js + // 2.移动子窗口位置。 + windowClass.moveTo(300, 300, (err, data) => { + if (err.code) { + console.error('Failed to move the window. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in moving the window. Data: ' + JSON.stringify(data)); + }); + // 2.改变子窗口大小。 + windowClass.resetSize(500, 1000, (err, data) => { + if (err.code) { + console.error('Failed to change the window size. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in changing the window size. Data: ' + JSON.stringify(data)); + }); + ``` + +3. 加载显示子窗口的具体内容。 + 使用`loadContent`和`show`接口加载显示子窗口的具体内容。 + + + ```js + // 3.为子窗口加载对应的目标页面。 + windowClass.loadContent("pages/page2", (err, data) => { + if (err.code) { + console.error('Failed to load the content. Cause: ' + JSON.stringify(err)); + return; + } + console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data)); + // 3.显示子窗口。 + windowClass.show((err, data) => { + if (err.code) { + console.error('Failed to show the window. Cause: ' + JSON.stringify(err)); + return; + } + console.info('Succeeded in showing the window. Data: ' + JSON.stringify(data)); + }); + }); + ``` + +4. 销毁子窗口。 + 当不再需要某些子窗口时,可根据场景的具体实现逻辑,使用`destroy`接口销毁子窗口。 + + + ```js + // 4.销毁子窗口。当不再需要某些子窗口时,可根据场景的具体实现逻辑,使用destroy接口销毁子窗口,此处以监听窗口区域外的点击事件实现子窗口的销毁。 + windowClass.on('touchOutside', () => { + console.info('touch outside'); + windowClass.destroy((err, data) => { + if (err.code) { + console.error('Failed to destroy the subwindow. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in destroying the subwindow. Data: ' + JSON.stringify(data)); + }); + }); + ``` + + +## 体验窗口沉浸式能力 + +在看视频、玩游戏等场景下,用户往往希望隐藏状态栏、导航栏等不必要的系统窗口,从而获得更佳的沉浸式体验。此时可以借助窗口沉浸式能力(窗口沉浸式能力都是针对应用主窗口而言的),达到预期效果。 + + +### 开发步骤 + +1. 获取主窗口对象。 + 沉浸式能力需要在成功获取应用主窗口对象的前提下进行。使用`window.getTopWindow`接口来获取得到主窗口。 + + + ```js + import window from '@ohos.window'; + + var mainWindowClass = null; + // 1.获取主窗口 + window.getTopWindow((err, data) => { + if (err.code) { + console.error('Failed to get the subWindow. Cause: ' + JSON.stringify(err)); + return; + } + console.info('Succeeded in getting subWindow. Data: ' + JSON.stringify(data)); + mainWindowClass = data; + }); + ``` + +2. 实现沉浸式效果。有以下三种方式: + - 方式一:调用`setFullScreen`接口,设置应用主窗口为全屏显示,此时导航栏、状态栏将隐藏,从而达到沉浸式效果。 + - 方式二:调用`setSystemBarEnable`接口,设置导航栏、状态栏不显示,从而达到沉浸式效果。 + - 方式三:调用`setLayoutFullScreen`接口,设置应用主窗口为全屏布局;然后调用`setSystemPropertites`接口,设置导航栏、状态栏的透明度、背景/文字颜色以及高亮图标等属性,使之保持与主窗口显示协调一致,从而达到沉浸式效果。 + + ```js + // 2.实现沉浸式效果。方式一:设置窗口全屏显示。 + var isFullScreen = true; + mainWindowClass.setFullScreen(isFullScreen, (err, data) => { + if (err.code) { + console.error('Failed to enable the full-screen mode. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in enabling the full-screen mode. Data: ' + JSON.stringify(data)); + }); + // 2.实现沉浸式效果。方式二:设置导航栏、状态栏不显示。 + var names = null; + mainWindowClass.setSystemBarEnable(names, (err, data) => { + if (err.code) { + console.error('Failed to set the system bar to be visible. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in setting the system bar to be visible. Data: ' + JSON.stringify(data)); + }); + // 2.实现沉浸式效果。 + //方式三:设置窗口为全屏布局,配合设置状态栏、导航栏的透明度、背景/文字颜色及高亮图标等属性,与主窗口显示保持协调一致。 + var isLayoutFullScreen = true; + mainWindowClass.setLayoutFullScreen(isLayoutFullScreen, (err, data) => { + if (err.code) { + console.error('Failed to set the window layout to full-screen mode. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in setting the window layout to full-screen mode. Data: ' + JSON.stringify(data)); + }); + var SystemBarProperties = { + statusBarColor: '#ff00ff', + navigationBarColor: '#00ff00', + //以下两个属性从API Version7开始支持 + isStatusBarLightIcon: false, + isNavigationBarLightIcon: false, + //以下两个属性从API Version8开始支持 + statusBarContentColor: '#ffffff', + navigationBarContentColor: '#ffffff' + }; + mainWindowClass.setSystemBarProperties(SystemBarProperties, (err, data) => { + if (err.code) { + console.error('Failed to set the system bar properties. Cause: ' + JSON.stringify(err)); + return; + } + console.info('Succeeded in setting the system bar properties. Data: ' + JSON.stringify(data)); + }); + ``` + +3. 加载显示沉浸式窗口的具体内容。 + 使用`loadContent`和`show`接口加载显示沉浸式窗口的具体内容。 + + + ```js + // 3.为沉浸式窗口加载对应的目标页面。 + mainWindowClass.loadContent("pages/page3", (err, data) => { + if (err.code) { + console.error('Failed to load the content. Cause: ' + JSON.stringify(err)); + return; + } + console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data)); + // 3.显示沉浸式窗口。 + mainWindowClass.show((err, data) => { + if (err.code) { + console.error('Failed to show the window. Cause: ' + JSON.stringify(err)); + return; + } + console.info('Succeeded in showing the window. Data: ' + JSON.stringify(data)); + }); + }); + ``` + diff --git a/zh-cn/application-dev/windowmanager/application-window-stage.md b/zh-cn/application-dev/windowmanager/application-window-stage.md new file mode 100644 index 0000000000000000000000000000000000000000..07f9d0503717c36d06eb1376befb745aab6874b7 --- /dev/null +++ b/zh-cn/application-dev/windowmanager/application-window-stage.md @@ -0,0 +1,406 @@ +# 管理应用窗口(Stage模型) + + +## 基本概念 + +- 窗口沉浸式能力:指对状态栏、导航栏等系统窗口进行控制,减少状态栏导航栏等系统界面的突兀感,从而使用户获得最佳体验的能力。 + 沉浸式能力只在应用主窗口作为全屏窗口时生效。通常情况下,应用子窗口(弹窗、悬浮窗口等辅助窗口)和处于自由窗口下的应用主窗口无法使用沉浸式能力。 + +- 悬浮窗:全局悬浮窗口是一种特殊的应用窗口,具备在应用主窗口和对应Ability退至后台后仍然可以在前台显示的能力。 + 悬浮窗口可以用于应用退至后台后,使用小窗继续播放视频,或者为特定的应用创建悬浮球等快速入口。应用在创建悬浮窗口前,需要申请对应的权限。 + + +## 场景介绍 + +在`Stage`模型下,管理应用窗口的典型场景有: + +- 设置应用主窗口属性及目标页面 + +- 设置应用子窗口属性及目标页面 + +- 体验窗口沉浸式能力 + +- 设置悬浮窗 + +以下分别介绍具体开发方式。 + + +## 接口说明 + +上述场景涉及的常用接口如下表所示。更多API说明请参见[API参考](../reference/apis/js-apis-window.md)。 + +| 实例名 | 接口名 | 描述 | +| -------- | -------- | -------- | +| WindowStage | getMainWindow(callback:AsyncCallback<Window>):void | 获取`WindowStage`实例下的主窗口。
此接口仅可在`Stage`模型下使用。 | +| WindowStage | loadContent(path:string,callback:AsyncCallback<void>):void | 为当前`WindowStage`的主窗口加载具体页面。
此接口仅可在`Stage`模型下使用。 | +| WindowStage | createSubWindow(name:string,callback:AsyncCallback<Window>):void | 创建子窗口。
此接口仅可在`Stage`模型下使用。 | +| window静态方法 | create(ctx:Context,id:string,type:WindowType,callback:AsyncCallback<Window>):void | 创建子窗口。
-`ctx`:为应用上下文信息。
-`type`:为创建的窗口类型。 | +| Window | loadContent(path:string,callback:AsyncCallback<void>):void | 为当前窗口加载具体页面。 | +| Window | setBackgroundColor(color:string,callback:AsyncCallback<void>):void | 设置窗口的背景色。 | +| Window | setBrightness(brightness:number,callback:AsyncCallback<void>):void | 设置屏幕亮度值。 | +| Window | setTouchable(isTouchable:boolean,callback:AsyncCallback<void>):void | 设置窗口是否为可触状态。 | +| Window | moveTo(x:number,y:number,callback:AsyncCallback<void>):void | 移动当前窗口位置。 | +| Window | resetSize(width:number,height:number,callback:AsyncCallback<void>):void | 改变当前窗口大小。 | +| Window | setFullScreen(isFullScreen:boolean,callback:AsyncCallback<void>):void | 设置窗口是否全屏显示。 | +| Window | setLayoutFullScreen(isLayoutFullScreen:boolean,callback:AsyncCallback<void>):void | 设置窗口布局是否为全屏布局。 | +| Window | setSystemBarEnable(names:Array<'status'\|'navigation'>):Promise<void> | 设置导航栏、状态栏是否显示。 | +| Window | setSystemBarProperties(systemBarProperties:SystemBarProperties,callback:AsyncCallback<void>):void | 设置窗口内导航栏、状态栏属性。
`systemBarProperties`:导航栏、状态栏的属性集合。 | +| Window | show(callback: AsyncCallback\): void | 显示当前窗口。 | +| Window | on(type:'touchOutside',callback:Callback<void>):void | 开启本窗口区域外的点击事件的监听。 | +| Window | destroy(callback: AsyncCallback<void>):void | 销毁当前窗口。 | + + +## 设置应用主窗口 + +在`Stage`模型下,应用主窗口由`Ability`创建并维护生命周期。在`Ability`的`onWindowStageCreate`回调中,通过`WindowStage`获取应用主窗口,即可对其进行属性设置等操作 + + +### 开发步骤 + +1. 获取应用主窗口。 + 通过`getMainWindow`接口获取应用主窗口。 + +2. 设置主窗口属性。 + 可设置主窗口的背景色、亮度值、是否可触等多个属性,开发者可根据需要选择对应的接口。本示例以设置“是否可触”属性为例。 + +3. 为主窗口加载对应的目标页面。 + 通过`loadContent`接口加载主窗口的目标页面。 + + +```ts +import Ability from '@ohos.application.Ability' + +class MainAbility extends Ability { + onWindowStageCreate(windowStage) { + // 1.获取应用主窗口。 + var windowClass = null; + windowStage.getMainWindow((err, data) => { + if (err.code) { + console.error('Failed to obtain the main window. Cause: ' + JSON.stringify(err)); + return; + } + windowClass = data; + console.info('Succeeded in obtaining the main window. Data: ' + JSON.stringify(data)); + // 2.设置主窗口属性。以设置"是否可触"属性为例。 + var isTouchable = true; + windowClass.setTouchable(isTouchable, (err, data) => { + if (err.code) { + console.error('Failed to set the window to be touchable. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in setting the window to be touchable. Data:' + JSON.stringify(data)); + }) + }) + // 3.为主窗口加载对应的目标页面。 + windowStage.loadContent("pages/page2", (err, data) => { + if (err.code) { + console.error('Failed to load the content. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data)); + }); + } +}; +``` + + +## 设置应用子窗口 + +开发者可以按需创建应用子窗口,如弹窗等,并对其进行属性设置等操作。 + + +### 开发步骤 + +1. 创建/获取应用子窗口。 + 通过`createSubWindow`接口创建应用子窗口。 + + 通过`getSubWindow`接口获取已创建的应用子窗口。 + +2. 设置子窗口属性。 + 子窗口创建成功后,可以改变其大小、位置等,还可以根据应用需要设置窗口背景色、亮度等属性。 + +3. 加载显示子窗口的具体内容。 + 通过`loadContent`和`show`接口加载显示子窗口的具体内容。 + +4. 销毁子窗口。 + 当不再需要某些子窗口时,可根据具体实现逻辑,使用`destroy`接口销毁子窗口。 + + + ```ts + import Ability from '@ohos.application.Ability' + + class MainAbility extends Ability { + onWindowStageCreate(windowStage) { + // 1.创建应用子窗口。 + var sub_windowClass = null; + 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)); + // 1.获取已创建的应用子窗口。 + windowStage.getSubWindow((err, data) => { + if (err.code) { + console.error('Failed to obtain the subWindow. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in obtaining the subWindow. Data: ' + JSON.stringify(data)); + sub_windowClass = data; + }); + // 2.子窗口创建成功后,设置子窗口的位置、大小及相关属性等。 + sub_windowClass.moveTo(300, 300, (err, data) => { + if (err.code) { + console.error('Failed to move the window. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in moving the window. Data: ' + JSON.stringify(data)); + }); + sub_windowClass.resetSize(500, 1000, (err, data) => { + if (err.code) { + console.error('Failed to change the window size. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in changing the window size. Data: ' + JSON.stringify(data)); + }); + // 3.为子窗口加载对应的目标页面。 + sub_windowClass.loadContent("pages/page3", (err, data) => { + if (err.code) { + console.error('Failed to load the content. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data)); + // 3.显示子窗口。 + sub_windowClass.show((err, data) => { + if (err.code) { + console.error('Failed to show the window. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in showing the window. Data: ' + JSON.stringify(data)); + }); + }); + // 4.销毁子窗口。当不再需要子窗口时,可根据具体实现逻辑,使用destroy对其进行销毁,此处以监听窗口区域外的点击事件为例实现子窗口的销毁。 + sub_windowClass.on('touchOutside', () => { + console.info('touch outside'); + sub_windowClass.destroy((err, data) => { + if (err.code) { + console.error('Failed to destroy the window. Cause: ' + JSON.stringify(err)); + return; + } + console.info('Succeeded in destroying the window. Data: ' + JSON.stringify(data)); + }); + }); + }) + } + }; + ``` + + +## 体验窗口沉浸式能力 + +在看视频、玩游戏等场景下,用户往往希望隐藏状态栏、导航栏等不必要的系统窗口,从而获得更佳的沉浸式体验。此时可以借助窗口沉浸式能力(窗口沉浸式能力都是针对应用主窗口而言的),达到预期效果。 + + +### 开发步骤 + +1. 获取应用主窗口。 + 通过`getMainWindow`接口获取应用主窗口。 + +2. 实现沉浸式效果。有以下三种方式: + - 方式一:调用`setFullScreen`接口,设置应用主窗口为全屏显示,此时导航栏、状态栏将隐藏,从而达到沉浸式效果。 + - 方式二:调用`setSystemBarEnable`接口,设置导航栏、状态栏不显示,从而达到沉浸式效果。 + - 方式三:调用`setLayoutFullScreen`接口,设置应用主窗口为全屏布局;然后调用`setSystemPropertites`接口,设置导航栏、状态栏的透明度、背景/文字颜色以及高亮图标等属性,使之保持与主窗口显示协调一致,从而达到沉浸式效果。 + +3. 加载显示沉浸式窗口的具体内容。 + 通过`loadContent`和`show`接口加载显示沉浸式窗口的具体内容。 + + + ```ts + import Ability from '@ohos.application.Ability' + + class MainAbility extends Ability { + onWindowStageCreate(windowStage) { + // 1.获取应用主窗口。 + var windowClass = null; + windowStage.getMainWindow((err, data) => { + if (err.code) { + console.error('Failed to obtain the main window. Cause: ' + JSON.stringify(err)); + return; + } + windowClass = data; + console.info('Succeeded in obtaining the main window. Data: ' + JSON.stringify(data)); + + // 2.实现沉浸式效果。方式一:设置应用主窗口为全屏显示。 + var isFullScreen = true; + windowClass.setFullScreen(isFullScreen, (err, data) => { + if (err.code) { + console.error('Failed to enable the full-screen mode. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in enabling the full-screen mode. Data: ' + JSON.stringify(data)); + }); + // 2.实现沉浸式效果。方式二:设置导航栏、状态栏不显示。 + var names = null; + windowClass.setSystemBarEnable(names, (err, data) => { + if (err.code) { + console.error('Failed to set the system bar to be visible. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in setting the system bar to be visible. Data: ' + JSON.stringify(data)); + }); + // 2.实现沉浸式效果。方式三:设置窗口为全屏布局,配合设置导航栏、状态栏的透明度、背景/文字颜色及高亮图标等属性,与主窗口显示保持协调一致。 + var isLayoutFullScreen = true; + windowClass.setLayoutFullScreen(isLayoutFullScreen, (err, data) => { + if (err.code) { + console.error('Failed to set the window layout to full-screen mode. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in setting the window layout to full-screen mode. Data: ' + JSON.stringify(data)); + }); + var SystemBarProperties = { + statusBarColor: '#ff00ff', + navigationBarColor: '#00ff00', + // 以下两个属性从API Version 7开始支持 + isStatusBarLightIcon: false, + isNavigationBarLightIcon: false, + // 以下两个属性从API Version 8开始支持 + statusBarContentColor: '#ffffff', + navigationBarContentColor: '#ffffff' + }; + windowClass.setSystemBarProperties(SystemBarProperties, (err, data) => { + if (err.code) { + console.error('Failed to set the system bar properties. Cause: ' + JSON.stringify(err)); + return; + } + console.info('Succeeded in setting the system bar properties. Data: ' + JSON.stringify(data)); + }); + }) + // 3.为沉浸式窗口加载对应的目标页面。 + windowStage.loadContent("pages/page2", (err, data) => { + if (err.code) { + console.error('Failed to load the content. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data)); + // 3.显示沉浸式窗口。 + windowStage.show((err, data) => { + if (err.code) { + console.error('Failed to show the window. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in showing the window. Data: ' + JSON.stringify(data)); + }); + }); + } + }; + ``` + + +## 设置悬浮窗 + +悬浮窗可以在已有的任务基础上,创建一个始终在前台显示的窗口。即使创建悬浮窗的任务退至后台,悬浮窗仍然可以在前台显示。开发者可以创建悬浮窗,并对悬浮窗进行属性设置等操作。 + + +### 开发步骤 + +1. 申请权限。 + 创建`WindowType.TYPE_FLOAT`即悬浮窗类型的窗口,需要在`module.json5`文件的`requestPermissions`对象中配置`ohos.permission.SYSTEM_FLOAT_WINDOW`权限。更多配置信息详见[应用包结构配置文件的说明](../quick-start/stage-structure.md#requestPermissions对象内部结构)。 + + > **说明:** + > 虽然悬浮窗具备始终在前台显示的能力,但如果创建悬浮窗的应用任务被系统回收,仍然会导致悬浮窗从界面移除。如果想要保持悬浮窗口始终在前台显示,请申请[长时任务](../task-management/background-task-overview.md#长时任务)。 + + + ```json + { + "module": { + "requestPermissions":[ + { + "name" : "ohos.permission.SYSTEM_FLOAT_WINDOW", + "usedScene": { + "abilities": [ + "MainAbility" + ], + "when":"inuse" + } + } + ] + } + } + ``` + +2. 创建悬浮窗。 + 通过`window.create`接口创建悬浮窗类型的窗口。 + +3. 对悬浮窗进行属性设置等操作。 + 悬浮窗窗口创建成功后,可以改变其大小、位置等,还可以根据应用需要设置悬浮窗背景色、亮度等属性。 + +4. 加载显示悬浮窗的具体内容。 + 通过`loadContent`和`show`接口加载显示悬浮窗的具体内容。 + +5. 销毁悬浮窗。 + + 当不再需要悬浮窗时,可根据具体实现逻辑,使用`destroy`接口销毁悬浮窗。 + + ```ts + import Ability from '@ohos.application.Ability' + import ExtensionContext from '@ohos.application.ServiceExtensionAbility'; + import window from '@ohos.window'; + + class MainAbility extends Ability { + onWindowStageCreate(windowStage) { + // 2. 创建悬浮窗。 + var windowClass = null; + window.create(this.context, "floatWindow", window.WindowType.TYPE_FlOAT, (err, data) => { + if (err.code) { + console.error('Failed to create the floatWindow. Cause: ' + JSON.stringify(err)); + return; + } + console.info('Succeeded in creating the floatWindow. Data: ' + JSON.stringify(data)); + windowClass = data; + // 3.悬浮窗窗口创建成功后,设置悬浮窗的位置、大小及相关属性等。 + windowClass.moveTo(300, 300, (err, data) => { + if (err.code) { + console.error('Failed to move the window. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in moving the window. Data: ' + JSON.stringify(data)); + }); + windowClass.resetSize(500, 1000, (err, data) => { + if (err.code) { + console.error('Failed to change the window size. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in changing the window size. Data: ' + JSON.stringify(data)); + }); + // 4.为悬浮窗加载对应的目标页面。 + windowClass.loadContent("pages/page4", (err, data) => { + if (err.code) { + console.error('Failed to load the content. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data)); + // 4.显示悬浮窗。 + windowClass.show((err, data) => { + if (err.code) { + console.error('Failed to show the window. Cause: ' + JSON.stringify(err)); + return; + } + console.info('Succeeded in showing the window. Data: ' + JSON.stringify(data)); + }); + }); + //5.销毁悬浮窗。当不再需要悬浮窗时,可根据具体实现逻辑,使用destroy对其进行销毁,此处以监听窗口区域外的点击事件为例实现悬浮窗的销毁。 + windowClass.on('touchOutside', () => { + console.info('touch outside'); + windowClass.destroy((err, data) => { + if (err.code) { + console.error('Failed to destroy the window. Cause: ' + JSON.stringify(err)); + return; + } + console.info('Succeeded in destroying the window. Data: ' + JSON.stringify(data)); + }); + }); + }); + } + }; + ``` diff --git a/zh-cn/application-dev/windowmanager/figures/windowMode.png b/zh-cn/application-dev/windowmanager/figures/windowMode.png new file mode 100644 index 0000000000000000000000000000000000000000..6d4b793d46343ff33efec41ce90c7418ba2fe779 Binary files /dev/null and b/zh-cn/application-dev/windowmanager/figures/windowMode.png differ diff --git a/zh-cn/application-dev/windowmanager/system-window-stage.md b/zh-cn/application-dev/windowmanager/system-window-stage.md new file mode 100644 index 0000000000000000000000000000000000000000..424fc51117a639e0119b0a55b71f9027412061e1 --- /dev/null +++ b/zh-cn/application-dev/windowmanager/system-window-stage.md @@ -0,0 +1,109 @@ +# 管理系统窗口(仅Stage模型支持) + +## 管理系统窗口概述 + +在`Stage`模型下, 允许系统应用创建和管理系统窗口,包括音量条、壁纸、通知栏、状态栏、导航栏等。具体支持的系统窗口类型见[API参考-WindowType](../reference/apis/js-apis-window.md)。 + + +## 接口说明 + +更多API说明请参见[API参考](../reference/apis/js-apis-window.md)。 + +| 实例名 | 接口名 | 描述 | +| -------- | -------- | -------- | +| window静态方法 | create(ctx:Context,id:string,type:WindowType,callback:AsyncCallback<Window>):void | 创建窗口。
-`ctx`:为应用上下文信息。当`Context`为[ServiceExtensionContext](..reference/apis/js-apis-service-extension-context.md)时,创建系统窗口。
-`type`:为创建的窗口类型。 | +| Window | resetSize(width:number,height:number,callback:AsyncCallback<void>):void | 改变当前窗口大小。 | +| Window | moveTo(x:number,y:number,callback:AsyncCallback<void>):void | 移动当前窗口位置。 | +| Window | loadContent(path:string,callback:AsyncCallback<void>):void | 为当前窗口加载具体页面。 | +| Window | show(callback: AsyncCallback\): void | 显示当前窗口。 | +| Window | on(type:'touchOutside',callback:Callback<void>):void | 开启本窗口区域外的点击事件的监听。 | +| Window | hide (callback: AsyncCallback\): void | 隐藏当前窗口。此接口为系统接口。 | +| Window | destroy(callback: AsyncCallback<void>):void | 销毁当前窗口。 | + + +## 开发步骤 + + +本文以音量条窗口为例,介绍系统窗口的基本开发和管理步骤。 + + +1. 创建系统窗口。 + 在[ServiceExtensionContext](..reference/apis/js-apis-service-extension-context.md)下,使用`window.create`接口创建音量条系统窗口。 + +2. 操作或设置系统窗口的属性。 + 系统窗口创建成功后,可以改变其大小、位置等,还可以根据需要设置系统窗口的背景色、亮度等属性。 + +3. 加载显示系统窗口的具体内容。 + + 通过`loadContent`和`show`接口加载显示音量条窗口的具体内容。 + +4. 隐藏/销毁系统窗口。 + 当不再需要音量条窗口时,可根据具体实现逻辑,使用`hide`接口或`destroy`接口对其进行隐藏或销毁。 + +```ts +import ExtensionContext from '@ohos.application.ServiceExtensionAbility'; +import window from '@ohos.window'; + +var windowClass = null; + +export default class ServiceExtensionAbility1 extends ExtensionContext { + onCreate(want) { + console.log("[Demo] MainAbility onCreate") + globalThis.abilityWant = want; + // 1.创建音量条窗口。 + var windowClass = null; + window.create(this.context, "volume", window.WindowType.TYPE_VOLUME_OVERLAY, (err, data) => { + if (err.code) { + console.error('Failed to create the volume window. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in creating the volume window.') + windowClass = data; + // 2.创建音量条窗口成功之后,可以改变其大小、位置或设置背景色、亮度等属性。 + windowClass.moveTo(300, 300, (err, data) => { + if (err.code) { + console.error('Failed to move the window. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in moving the window. Data: ' + JSON.stringify(data)); + }); + windowClass.resetSize(500, 1000, (err, data) => { + if (err.code) { + console.error('Failed to change the window size. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in changing the window size. Data: ' + JSON.stringify(data)); + }); + // 3.为音量条窗口加载对应的目标页面。 + windowClass.loadContent("pages/page_volume", (err, data) => { + if (err.code) { + console.error('Failed to load the content. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data)); + // 3.显示音量条窗口。 + windowClass.show((err, data) => { + if (err.code) { + console.error('Failed to show the window. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in showing the window. Data: ' + JSON.stringify(data)); + }); + }); + // 4.隐藏/销毁音量条窗口。当不再需要音量条时,可根据具体实现逻辑,对其进行隐藏或销毁。 + // 此处以监听音量条区域外的点击事件为例实现音量条窗口的隐藏。 + windowClass.on('touchOutside', () => { + console.info('touch outside'); + windowClass.hide((err, data) => { + if (err.code) { + console.error('Failed to hide the window. Cause: ' + JSON.stringify(err)); + return; + } + console.info('Succeeded in hidinging the window. Data: ' + JSON.stringify(data)); + }); + }); + }); + } +}; +``` + diff --git a/zh-cn/application-dev/windowmanager/window-guidelines.md b/zh-cn/application-dev/windowmanager/window-guidelines.md deleted file mode 100644 index 7758fec39628b8c33c9b6b17f9ccb86e9fec2d60..0000000000000000000000000000000000000000 --- a/zh-cn/application-dev/windowmanager/window-guidelines.md +++ /dev/null @@ -1,107 +0,0 @@ -# 窗口开发指导 - -## 场景介绍 -窗口的接口层在应用进程运行,负责对页面布局的加载,和提供应用程序接口。 -通过调用窗口接口可以实现窗口创建与销毁,窗口的位置、大小布局,以及进入沉浸式等。 - -## 接口说明 -窗口开放的能力如下:Window类,具体的API详见[接口文档](../reference/apis/js-apis-window.md)。 - -**表1** 窗口主要接口API - -| 接口名 | 描述 | -| :----------------------------------------------------------- | :--------------------------------------------- | -| create(id: string, type: WindowType, callback: AsyncCallback\): void | 创建子窗口。 | -| moveTo(x: number, y: number): Promise\ | 移动窗口位置,x值为正表示右移,y为正表示下移。 | -| resetSize(width: number, height: number): Promise\ | 改变当前窗口大小。 | -| hide(): Promise\ | 隐藏当前窗口。 | -| destroy(): Promise\ | 销毁当前窗口。 | - -## 开发步骤 - -### 创建主窗口 - -在当前模型下,应用启动时会自动创建主窗口,由应用管理窗口的生命周期,隐藏及销毁由应用管理。 -### 创建子窗口 -当前可以通过`create`接口创建子窗口。具体示例代码如下: - -```js - import window from '@ohos.window'; - var windowClass = null; - let promise = window.create("subWindow", window.WindowType.TYPE_APP); - promise.then((data)=> { - windowClass = data; - console.info('SubWindow created. Data: ' + JSON.stringify(data)) - }).catch((err)=>{ - console.error('Failed to create the subWindow. Cause: ' + JSON.stringify(err)); - }); -``` - -### 获取窗口对象 - -- 应用内可以通过`getTopWindow`来获取当前应用内最后显示的窗口。具体示例代码如下: - -```js - var windowClass = null; - let promise = window.getTopWindow(); - promise.then((data)=> { - windowClass = data; - console.info('Succeeded in obtaining the top window. Data: ' + JSON.stringify(data)) - }).catch((err)=>{ - console.error('Failed to obtain the top window. Cause: ' + JSON.stringify(err)); - }) -``` - -- 应用内也可以通过`Find`来获取已经创建的子窗口。具体示例代码如下: - -```js - var windowClass = null; - let promise = window.find("subWindow"); - promise.then((data)=> { - windowClass = data; - console.info('window found. Data: ' + JSON.stringify(data)) - }).catch((err)=>{ - console.error('Failed to find the Window. Cause: ' + JSON.stringify(err)); - }); -``` - -### 窗口的隐藏和销毁 - -在已经获取到窗口对象的前提下,可以调用`hide`、`destroy`来隐藏和销毁已经创建的窗口对象。具体示例代码如下: - -```js - let promise = windowClass.hide(); - promise.then((data)=> { - console.info('window hidden. Data: ' + JSON.stringify(data)) - windowClass.destroy((err, data) => { - if (err.code) { - console.error('Failed to destroy the window. Cause:' + JSON.stringify(err)); - return; - } - console.info('Succeeded in destroying the window. Data: ' + JSON.stringify(data)) - }) - }).catch((err)=>{ - console.error('Failed to hide the window. Cause: ' + JSON.stringify(err)); - }) -``` - -### 设置沉浸式窗口 - -在已经获取到应用窗口对象的前提下,调用`setFullScreen`来设置窗口进入全屏沉浸式。 - -示例代码如下: - -```js -import window from '@ohos.window'; -try { - const win = await window.getTopWindow() - await win.setFullScreen(true) -} catch (err) { - console.log(`setFullScreen fail, code = ${err.code}`) -} -``` - -## 相关实例 -针对窗口开发,有以下相关实例可供参考: -- [`Window`:窗口(eTS)(API9)](https://gitee.com/openharmony/app_samples/tree/master/Graphics/Window) - diff --git a/zh-cn/application-dev/windowmanager/window-overview.md b/zh-cn/application-dev/windowmanager/window-overview.md index 72f7a17f350a53dc5e56eb3203aa383c1263a306..f3e2ba39243ce42c7052249b967d9467550f8715 100644 --- a/zh-cn/application-dev/windowmanager/window-overview.md +++ b/zh-cn/application-dev/windowmanager/window-overview.md @@ -1,13 +1,75 @@ # 窗口开发概述 -**窗口子系统**提供窗口管理的基础能力,是系统图形界面显示所需的基础子系统。 -窗口系统的作用,是提供一种机制,让多个应用界面复用同一块物理屏幕进行显示和交互。每个应用程序中,需要实现固定窗口区域内的交互界面设计,窗口作用应用界面的显示容器,而窗口系统负责将这些交互界面组织成最终用户见到的形态。 + +## 窗口模块的定义 + +窗口模块用于在同一块物理屏幕上,提供多个应用界面显示、交互的机制。 + +- 对应用开发者而言,窗口模块提供了界面显示和交互能力。 + +- 对终端用户而言,窗口模块提供了控制应用界面的方式。 + +- 对整个操作系统而言,窗口模块提供了不同应用界面的组织管理逻辑。 + + +## 窗口模块的用途 + +在OpenHarmony中,窗口模块主要负责以下职责: + +- 提供应用和系统界面的窗口对象。应用开发者通过窗口加载UI界面,实现界面显示功能。 + +- 组织不同窗口的显示关系,即维护不同窗口间的叠加层次和位置属性。应用和系统的窗口具有多种类型,不同类型的窗口具有不同的默认位置和叠加层次(Z轴高度)。同时,用户操作也可以在一定范围内对窗口的位置和叠加层次进行调整。 + +- 提供窗口装饰。窗口装饰指窗口标题栏和窗口边框。窗口标题栏通常包括窗口最大化、最小化及关闭按钮等界面元素,具有默认的点击行为,方便用户进行操作;窗口边框则方便用户对窗口进行拖拽缩放等行为。窗口装饰是系统的默认行为,开发者可选择启用/禁用,无需关注UI代码层面的实现。 + +- 提供窗口动效。在窗口显示、隐藏及窗口间切换时,窗口模块通常会添加动画效果,以使各个交互过程更加连贯流畅。在OpenHarmony中,应用窗口的动效为默认行为,不需要开发者进行设置或者修改。 + +- 指导输入事件分发。即根据当前窗口的状态或焦点,进行事件的分发。触摸和鼠标事件根据窗口的位置和尺寸进行分发,而键盘事件会被分发至焦点窗口。应用开发者可以通过窗口模块提供的接口设置窗口是否可以触摸和是否可以获焦。 + ## 基本概念 -**沉浸式**:应用窗口跟状态栏与导航栏颜色一致,视觉上融合。 +### 窗口类型 + +OpenHarmony的窗口模块将窗口界面分为系统窗口、应用窗口两种基本类型。 + +- 系统窗口 + 系统窗口指完成系统特定功能的窗口。如音量条、壁纸、通知栏、状态栏、导航栏等。 + +- 应用窗口 + 应用窗口区别于系统窗口,指与应用显示相关的窗口。根据显示内容的不同,应用窗口又分为应用主窗口、应用子窗口两种类型。 + + - 应用主窗口 + 应用主窗口用于显示应用界面,会在"任务管理界面"显示。 + - 应用子窗口 + 应用子窗口用于显示应用的弹窗、悬浮窗等辅助窗口,不会在"任务管理界面"显示。 + + +### 应用窗口模式 + +应用窗口模式指应用主窗口启动时的显示方式。OpenHarmony目前支持全屏、分屏、自由窗口三种应用窗口模式。这种对多种应用窗口模式的支持能力,也称为操作系统的“多窗口能力”。 + + +- 全屏:应用主窗口启动时铺满整个屏幕。 + +- 分屏:应用主窗口启动时占据屏幕的某个部分,当前支持二分屏。两个分屏窗口之间具有分界线,可通过拖拽分界线调整两个部分的窗口尺寸。 + +- 自由窗口:自由窗口的大小和位置可自由改变。同一个屏幕上可同时显示多个自由窗口,这些自由窗口按照打开或者获取焦点的顺序在Z轴排布。当自由窗口被点击或触摸时,将导致其Z轴高度提升,并获取焦点。 + + +![windowMode](figures/windowMode.png) + + +## 实现原理 + +当前窗口的实现和开发与应用开发模型相关联,不同模型下的接口功能略有区别。当前应用开发模型分为FA模型和Stage模型。 + +两个模型的整体架构和设计思想,详见[FA模型综述](../ability/fa-brief.md)和[Stage模型综述](../ability/stage-brief.md)。 + +针对窗口开发,推荐使用Stage模型进行相关开发。 + -## 运作机制 +## 约束与限制 -为了将图形界面显示在屏幕上,应用和系统需要向窗口系统申请窗口对象,这通常代表了屏幕上一块矩形区域,具有位置、宽高、和叠加层次等属性。同时,窗口对象也负责加载界面中UI框架的根节点,应用程序的UI界面就通过这个根节点在窗口中加载显示。 \ No newline at end of file +在FA模型下,不支持系统窗口的相关开发。