窗口开发常见问题
========

#### 如何在应用A启动过程中拉起另一个应用B

**解决措施**

应用A调用[on('windowStageEvent')](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-windowstage#onwindowstageevent9)接口监听[WindowStageEvent.ACTIVE](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-e#windowstageeventtype9)事件后调用[startAbility](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-inner-application-uiabilitycontext#startability)接口拉起应用B。

**代码示例**

// applicationA EntryAbility.ts
import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
import { Want, StartOptions } from '@kit.AbilityKit';

export default class EntryAbility extends UIAbility {
    onWindowStageCreate(windowStage: window.WindowStage): void {
        let want: Want = {
            deviceId: '',
            bundleName: 'com.example.applicationB',
            abilityName: 'EntryAbility'
        };

        let options: StartOptions = {
            displayId: 0
        };

        windowStage.on('windowStageEvent', (data) => {
            let eventType: window.WindowStageEventType = data;
            // 监听应用A切换到ACTIVE状态
            if (eventType === window.WindowStageEventType.ACTIVE) {
                try {
                    // 拉起应用B
                    this.context.startAbility(want, options, (err: BusinessError) => {
                        if (err.code) {
                            // 处理业务逻辑错误
                            console.error(\`Failed to start ability, code is ${err.code}, message is ${err.message}.\`);
                            return;
                        }
                        // 执行正常业务
                        console.info('Succeeded in starting Ability.');
                    });
                } catch (err) {
                    // 处理入参错误异常
                    let code = (err as BusinessError).code;
                    let message = (err as BusinessError).message;
                    console.error(\`Failed to start ability, code is ${code}, message is ${message}.\`);
                }
            }
        });
    }
}

#### 如何动态获取窗口宽高

在应用开发中，动态获取窗口宽高主要用于实现响应式布局，以适应不同尺寸的设备或窗口状态变化（如分屏、最大化恢复、拖拽缩放等）。

推荐使用[getMainWindowSync()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-windowstage#getmainwindowsync9)、[getMainWindow()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-windowstage#getmainwindow9-1)、[getSubWindow()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-windowstage#getsubwindow9-1)中的任一方法获取到Window实例（windowClass），再通过此实例调用[getWindowProperties()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#getwindowproperties9)接口得到其属性WindowProperties，通过属性获取窗口宽高即可。示例代码如下：

import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  // ...
  onWindowStageCreate(windowStage: window.WindowStage) {
    console.info('onWindowStageCreate');
    let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口
    if (!windowClass) {
      console.info('windowClass is null');
    }
    try {
      let properties = windowClass.getWindowProperties();
      let rect = properties.windowRect;
      let windowWidth = rect.width;  // 窗口宽度，单位px
      let windowHeight = rect.height; // 窗口高度，单位px
      console.info(\`Window Size: ${windowWidth} x ${windowHeight}\`);
    } catch (exception) {
      console.error('Failed to obtain the window properties. Cause: ' + JSON.stringify(exception));
    }
  }
}

#### 如何获取软键盘高度

固定态软键盘为一种特定的避让区域类型，[AvoidAreaType](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-e#avoidareatype7)中对应为固定态软键盘（TYPE\_KEYBOARD）类型，可以通过[getWindowAvoidArea()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#getwindowavoidarea9)和[on('avoidAreaChange')](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#onavoidareachange9)动态监听软键盘避让区高度的变化。

另外，开发者也可以通过[on('keyboardHeightChange')](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#onkeyboardheightchange7)接口监听软键盘的占用高度。与避让区域不同的是，此接口回调仅返回软键盘的高度数值（number），而[on('avoidAreaChange')](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#onavoidareachange9)回调会返回整个软键盘区域（[Rect](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-i#rect7)）。

import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  // ...
  onWindowStageCreate(windowStage: window.WindowStage) {
    console.info('onWindowStageCreate');
    // 获取应用主窗口
    let windowClass: window.Window = windowStage.getMainWindowSync();
    if (!windowClass) {
      console.info('windowClass is null');
    }
    try {
      // 获取软键盘避让区高度
      let keyboardHeight = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE\_KEYBOARD).bottomRect.height;
      // 动态监听软键盘避让区高度
      windowClass.on('avoidAreaChange', (data) => {
        if (data.type == window.AvoidAreaType.TYPE\_KEYBOARD) {
          keyboardHeight = data.area.bottomRect.height;
        }
      });
    } catch (exception) {
      console.error(\`Failed to enable the listener for system avoid area changes. Cause code: ${exception.code}, message: ${exception.message}\`);
    }
  }
}

#### 如何获取PC设备顶部系统默认标题栏的高度

通过调用[getWindowDecorHeight()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#getwindowdecorheight11)获取窗口的标题栏高度。

示例代码如下所示：

import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  // ...
  onWindowStageCreate(windowStage: window.WindowStage) {
    console.info('onWindowStageCreate');
    // 获取应用主窗口
    let windowClass: window.Window = windowStage.getMainWindowSync();
    if (!windowClass) {
      console.info('windowClass is null');
    }
    windowClass.setUIContent('pages/WindowPage').then(() => {
      try {
        let height = windowClass?.getWindowDecorHeight();
        console.info(\`Succeeded in getting the height of window decor: ${height}\`);
      } catch (exception) {
        console.error(\`Failed to get the height of window decor. Cause code: ${exception.code}, message: ${exception.message}\`);
      }
    })
  }
}

#### 如何实现或判断窗口沉浸式布局

[沉浸式布局](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/immersive-window-feature#沉浸式布局)是一种让应用可布局区域拓展至整个窗口显示区域的状态。

非[自由窗口](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/window-terminology#freeform-window自由窗口)可以通过调用[setWindowLayoutFullScreen()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setwindowlayoutfullscreen9)设置沉浸式布局；自由窗口可以通过[setWindowDecorVisible()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setwindowdecorvisible11)接口控制窗口标题栏显隐，当标题栏隐藏时，窗口处于沉浸式布局。

可以通过[isImmersiveLayout()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#isimmersivelayout20)判断当前窗口是否处于沉浸式布局。

示例代码如下所示：

import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  // ...
  onWindowStageCreate(windowStage: window.WindowStage) {
    console.info('onWindowStageCreate');
    // 获取应用主窗口
    let windowClass: window.Window = windowStage.getMainWindowSync();
    if (!windowClass) {
      console.info('windowClass is null');
    }
    try {
      // 设置沉浸式布局
      let promise = windowClass.setWindowLayoutFullScreen(true);
      // 判断当前窗口是否处于沉浸式布局
      let isImmersiveLayout = windowClass.isImmersiveLayout();
      console.info(\`isImmersiveLayout: ${isImmersiveLayout}\`);
    } catch (exception) {
      console.error('Failed to obtain isImmersiveLayout. Cause: ' + JSON.stringify(exception));
    }
  }
}

#### 如何隐藏状态栏和底部导航区域

可以调用[setSpecificSystemBarEnabled()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setspecificsystembarenabled11)隐藏状态栏和底部导航区域。

示例代码如下所示：

import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  // ...
  onWindowStageCreate(windowStage: window.WindowStage) {
    console.info('onWindowStageCreate');
    // 获取应用主窗口
    let windowClass: window.Window = windowStage.getMainWindowSync();
    if (!windowClass) {
      console.info('windowClass is null');
    }
    try {
      // 隐藏状态栏
      windowClass.setSpecificSystemBarEnabled('status', false);
      // 隐藏底部导航区域
      windowClass.setSpecificSystemBarEnabled('navigationIndicator', false);
    } catch (exception) {
      console.error('Failed to obtain isImmersiveLayout. Cause: ' + JSON.stringify(exception));
    }
  }
}

#### 如何获取状态栏高度

状态栏为一种特定的避让区域类型，[AvoidAreaType](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-e#avoidareatype7)中对应为系统栏（TYPE\_SYSTEM）类型。

主窗口全屏时，可以通过[getWindowAvoidArea()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#getwindowavoidarea9)获取到包含状态栏的避让区域[AvoidArea](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-i#avoidarea7)，间接获取到状态栏的高度。

示例代码如下所示：

import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  // ...
  onWindowStageCreate(windowStage: window.WindowStage) {
    console.info('onWindowStageCreate');
    let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口
    if (!windowClass) {
      console.info('windowClass is null');
    }
    try {
      // 获取状态栏避让区高度
      let statusBarHeight = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE\_SYSTEM).topRect.height;
    } catch (exception) {
      console.error(\`Failed to enable the listener for system avoid area changes. Cause code: ${exception.code}, message: ${exception.message}\`);
    }
  }
}

#### 如何设置窗口背景透明

可以通过调用[setWindowBackgroundColor](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setwindowbackgroundcolor9)接口，传入'#00XXXXXX'（其中X代表任意十六进制数字）或者透明的[ColorMetrics](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-arkui-graphics#colormetrics12)实现窗口背景透明。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/cb/v3/TQS0ynL5Q6G8F2TOpccNIA/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132330Z&HW-CC-Expire=86400&HW-CC-Sign=D193372BC72D89BB32B4881E5A42D4749EC7DFDF6E97514FA12F2E4C223BDFA0)

*   在支持[自由窗口](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/window-terminology#freeform-window自由窗口)的设备上，存在窗口容器，窗口容器背景色覆盖整个窗口区域，包括标题栏和内容区域。调用[setWindowBackgroundColor](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setwindowbackgroundcolor9)接口仅可设置应用内容背景色，此时会透出窗口容器背景色。
    
*   在PC/2in1和Tablet设备上可以调用[setWindowContainerColor()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setwindowcontainercolor20)接口设置容器透明，在其他设备上暂不支持设置容器背景色。
    

示例代码如下所示：

import { BusinessError } from '@kit.BasicServicesKit';
import { ColorMetrics } from '@kit.ArkUI';
import { window } from '@kit.ArkUI';

let storage: LocalStorage = new LocalStorage();
storage.setOrCreate('storageSimpleProp', 121);
windowClass.loadContent("pages/page2", storage, (err: BusinessError) => {
  let errCode: number = err.code;
  if (errCode) {
  console.error(\`Failed to load the content. Cause code: ${err.code}, message: ${err.message}\`);
  return;
  }
  console.info('Succeeded in loading the content.');
  // 采用ARGB方式
  let color1: string = '#0000FF33';
  // 采用ColorMetrics方式
  let color2: ColorMetrics = ColorMetrics.numeric(0x00112233);
  try {
    windowClass?.setWindowBackgroundColor(color1);
    windowClass?.setWindowBackgroundColor(color2);
  } catch (exception) {
    console.error(\`Failed to set the background color. Cause code: ${exception.code}, message: ${exception.message}\`);
  };
});

#### 如何实现横竖屏切换

需要先获取到主窗实例，然后调用[setPreferredOrientation()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setpreferredorientation9-1)接口设置窗口方向。更多详细信息请参考[窗口旋转](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/window-rotation)。

示例代码如下所示：

import { BusinessError } from '@kit.BasicServicesKit'
import { common } from '@kit.AbilityKit'
import { window } from '@kit.ArkUI'

@Entry
@Component
struct OrientationTestView {
  private orientation: number =  1;
  private context = this.getUIContext().getHostContext() as common.UIAbilityContext;
  private windowClass = (this.context as common.UIAbilityContext).windowStage.getMainWindowSync();
  setOrientation(orientation: number) {
    this.windowClass.setPreferredOrientation(orientation).then(() => {
      console.info('setWindowOrientation: ' + orientation + ' Succeeded.');
    }).catch((err: BusinessError) => {
      console.error('setWindowOrientation: ' + orientation + ' Failed. Cause: ' + JSON.stringify(err));
    })
  }
  build() {
    Column() {
      Button('changeOrientation')
        .onClick(() => {
          this.setOrientation(this.orientation++ % 4 + 1)
        })
    }
    .height('100%')
    .width('100%')
    .margin({'top' : 100})
  }
}

更多内容请参考：

*   [最佳实践：横竖屏切换](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-landscape-and-portrait-development)
    
*   [Orientation](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-e#orientation9)
    

#### 如何保持屏幕为横屏/竖屏，不随传感器旋转

通过[setPreferredOrientation()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setpreferredorientation9-1)接口设置应用的旋转策略为LANDSCAPE，则应用保持在横屏；设置为PORTRAIT，则应用保持在竖屏；设置为LOCKED时，可以锁定当前应用方向，不随屏幕旋转（不建议使用LOCKED，可能会发生非预期的方向改变）。

对于单一页面（Navigation）的禁用旋转，可以通过设置组件的[preferredOrientation](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-navdestination#preferredorientation19)属性来实现，如果设置为横屏、竖屏、反向横屏或反向竖屏中某一方向，则该页面无法旋转到其他方向，从而实现页面级的旋转禁用。

#### 如何获取设备的横竖屏状态

先通过[display.getDefaultDisplaySync()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-display#displaygetdefaultdisplaysync9)获取当前默认的Display实例对象。

再通过该实例对象获取对应的[Orientation](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-display#orientation10)属性，以判断当前设备的横竖屏状态。

Orientation是显示设备当前显示的方向枚举，具体包括以下四种类型：

| 名称 | 值 | 说明 |
| :-- | :-- | :-- |
| PORTRAIT | 0 | 表示设备当前以竖屏方式显示。 |
| LANDSCAPE | 1 | 表示设备当前以横屏方式显示。 |
| PORTRAIT\_INVERTED | 2 | 表示设备当前以反向竖屏方式显示。 |
| LANDSCAPE\_INVERTED | 3 | 表示设备当前以反向横屏方式显示。 |

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/f2/v3/RGBusb0xQs-h6A1UgmBVjw/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132330Z&HW-CC-Expire=86400&HW-CC-Sign=A3F9402429665044912D233ABD5771B78F0F4F621EA7EC24C62FF3D28C1952D8)

通过[setPreferredOrientation](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setpreferredorientation9-1)接口设置旋转策略为LANDSCAPE，此时通过以上步骤获取到的[Orientation](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-display#orientation10)属性为反向横屏（即LANDSCAPE\_INVERTED），这是因为窗口的方向与屏幕的方向定义不一致。开发者也可以通过[convertOrientationAndRotation()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#convertorientationandrotation23)来获取转换结果。

示例代码如下所示：

import { display } from '@kit.ArkUI';

let displayClass: display.Display | null = null;
try {
  displayClass = display.getDefaultDisplaySync();
  let orientation = displayClass.Orientation;
} catch (exception) {
  console.error(\`Failed to get default display. Code: ${exception.code}, message: ${exception.message}\`);
}

#### 如何设置应用默认横屏宽高比例

应用开发中，推荐使用[setContentAspectRatio()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setcontentaspectratio21)设置窗口内容布局的比例。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/b9/v3/JWgr6zkUSuCJ6RqgeivsZQ/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132330Z&HW-CC-Expire=86400&HW-CC-Sign=5408CCDB5CA5A3B6665B7E14A62DFC5D286A0DCF970C2A1D49A514B7CF0CB202)

*   根据相同的ratio参数调整窗口宽高时，窗口宽高会跟随窗口边框装饰尺寸或可见性变化而调整。
    
*   通过[setWindowDecorVisible](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setwindowdecorvisible11)将窗口标题栏设置为不可见时，窗口内容区域将占据原本标题栏的高度空间。
    
*   通过其他接口如[resize](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#resize9-1)、[resizeAsync](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#resizeasync12)设置窗口大小时，不受ratio约束。
    
*   仅主窗可设置，且仅在自由悬浮窗口模式（即窗口模式为window.WindowStatusType.FLOATING）下生效。
    
*   API version 21以前的版本，请使用[setAspectRatio()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setaspectratio10)设置窗口内容布局。
    

示例代码如下：

// EntryAbility.ets
import { UIAbility } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  // ...
  onWindowStageCreate(windowStage: window.WindowStage): void {
    try {
      let windowClass = windowStage.getMainWindowSync();
      let ratio = 1.0;
      let promise = windowClass.setContentAspectRatio(ratio, true, true);
      promise.then(() => {
        console.info('Succeeded in setting aspect ratio of window.');
      }).catch((err: BusinessError) => {
        console.error(\`Failed to set the aspect ratio of window. Cause code: ${err.code}, message: ${err.message}\`);
      });
    } catch (exception) {
      console.error(\`Failed to set the aspect ratio of window. Cause code: ${exception.code}, message: ${exception.message}\`);
    }
  }
}

#### 如何设置窗口支持的显示模式supportWindowMode

在应用开发中， 推荐通过[module.json5](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/module-configuration-file)配置文件中的[abilities标签](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/module-configuration-file#abilities标签)的supportWindowMode字段设置窗口支持的显示模式。

supportWindowMode支持的取值如下：

| 配置值 | 模式 |
| :-- | :-- |
| "fullscreen" | 全屏模式 |
| "split" | 分屏模式 |
| "floating" | 自由悬浮窗口模式 |

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/6b/v3/ggCD7NkwRwmlRbulQEJ6kg/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132330Z&HW-CC-Expire=86400&HW-CC-Sign=FE264A9594833E22032BE1CD7D5BAE5725439B1457AEF6741F89B41BD9B48BB3)

*   supportWindowMode字段类型为字符串数组，可缺省，缺省值为\["fullscreen", "split", "floating"\]。
    
*   在[自由窗口](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/window-terminology#freeform-window自由窗口)状态下同时配置fullscreen和split时，如果应用的[targetAPIVersion](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/app-configuration-file#配置文件标签)小于15，窗口将以自由悬浮窗口模式启动；如果应用的[targetAPIVersion](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/app-configuration-file#配置文件标签)大于等于15，窗口将以全屏模式启动。
    

module.json5配置示例如下：

{
  "module": {
    "abilities": \[
      {
        "name": "EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ets",
        "description": "$string:EntryAbility\_desc",
        "displayName": "$string:EntryAbility\_displayName",
        "windowSize": {
          "minWidth": 320,
          "minHeight": 240
        },
        // 控制支持的窗口模式
        "supportWindowMode": \["fullscreen", "split", "floating"\],
        "launchType": "standard",
        "excludeFromMissions": false
      }
    \]
  }
}

除以上配置方式外，应用可参考以下几种方式配置窗口支持的模式：

*   使用[metadata](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/window-config-m)标签配置，name为'ohos.ability.window.supportWindowModeInFreeMultiWindow'，该字段配置仅在自由多窗下生效。
    
*   在启动UIAbility时，通过[StartOptions](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-app-ability-startoptions#startoptions)中的supportWindowModes字段指定窗口是否显示最大化/窗口化/分屏按键。
    
*   在启动后，可通过调用[setSupportedWindowModes()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-windowstage#setsupportedwindowmodes15)接口动态修改当前主窗口支持的窗口模式。
    

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/d8/v3/Pc3f-hIESxe0prA7cBjSlw/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132330Z&HW-CC-Expire=86400&HW-CC-Sign=273D0BB018CDD133F6071125CBF184302B4C0EE8A6D84DEC31942B0A33A667F9)

自由多窗下的可支持窗口模式可以采用多种方法进行配置，配置优先级为：

通过[setSupportedWindowModes](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-windowstage#setsupportedwindowmodes15)接口配置 > 通过StartAbility配置[StartOption](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-app-ability-startoptions#startoptions)中的SupportWindowMode > 使用metadata配置 > 配置module.json5中[abilities](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/module-configuration-file#abilities标签)标签下的SupportWindowMode属性。

#### 如何判断当前窗口是否为自由悬浮窗口模式

在应用开发中，有以下两种方式可判断应用是否处于自由悬浮窗口模式。

*   可通过[getWindowStatus()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#getwindowstatus12)直接查询当前的窗口模式。当WindowStatusType为FLOATING时，表示应用处于自由悬浮窗口模式。
    
    不同返回值及对应的窗口模式如下表所示：
    
    | 名称 | 值 | 说明 |
    | :-- | :-- | :-- |
    | UNDEFINED | 0 | 表示APP未定义窗口模式。 |
    | FULL\_SCREEN | 1 | 
    表示APP全屏模式。
    
    [自由窗口](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/window-terminology#freeform-window自由窗口)状态下，窗口铺满整个屏幕，默认无dock栏、标题栏和状态栏显示。
    
    可通过[maximize()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#maximize12)和[setTitleAndDockHoverShown()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#settitleanddockhovershown14)配置，当hover到热区时是否显示标题栏和dock栏。
    
    当maximize()和setTitleAndDockHoverShown()接口都调用时，以最后调用设置的效果为准。
    
    非[自由窗口](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/window-terminology#freeform-window自由窗口)状态下，窗口铺满整个屏幕，无标题栏和dock栏显示。可通过[setSpecificSystemBarEnabled()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setspecificsystembarenabled11)配置是否显示状态栏。
    
     |
    | MAXIMIZE | 2 | 表示APP窗口最大化模式，在PC/2in1设备中，窗口铺满整个屏幕，有dock栏和状态栏。 |
    | MINIMIZE | 3 | 表示APP窗口最小化模式。 |
    | FLOATING | 4 | 表示APP自由悬浮窗口模式。 |
    | SPLIT\_SCREEN | 5 | 表示APP分屏模式。 |
    
*   可通过[on('windowStatusChange')](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#onwindowstatuschange11)接口监听窗口模式变化。
    
    如果应用需要在窗口模式发生变化时（例如从全屏切换到自由悬浮窗口模式）立即做出响应，可以使用此接口监听窗口模式变化，以实现对应业务适配。
    
    import { UIAbility } from '@kit.AbilityKit';
    import { window } from '@kit.ArkUI';
    
    export default class EntryAbility extends UIAbility {
      // ...
      onWindowStageCreate(windowStage: window.WindowStage) {
        console.info('onWindowStageCreate');
        let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口
        if (!windowClass) {
          console.info('windowClass is null');
        }
        try {
          // 注册窗口状态变化监听
          windowClass.on('windowStatusChange', (windowStatusType: window.WindowStatusType) => {
            console.info(\`status change, new status: ${windowStatusType}\`);
          });
        } catch (error) {
          console.error(\`status listen err: ${JSON.stringify(error)}\`);
        }
        // 注意：在合适的时机，例如组件销毁时，记得取消监听
        // windowClass.off('windowStatusChange');
      }
    }
    
*   可通过[on('windowStatusDidChange')](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#onwindowstatusdidchange20)接口监听窗口模式变化。
    
    使用此接口开启窗口模式变化的监听后，当窗口windowStatus发生变化后进行通知（此时窗口[Rect](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-i#rect7)属性已经完成更新）。
    
    import { window } from '@kit.ArkUI';
    
    try {
      // 请先获取Window实例
      windowClass.on('windowStatusDidChange', (WindowStatusType) => {
        console.info(\`Succeeded in enabling the listener for window status changes. Data: ${JSON.stringify(WindowStatusType)}\`);
      });
    } catch (exception) {
      console.error(\`Failed to unregister callback. Cause code: ${exception.code}, message: ${exception.message}\`);
    }
    

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/ac/v3/NscXyI61QuK4JqkjSLe-NA/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132330Z&HW-CC-Expire=86400&HW-CC-Sign=3755BEB238A8185499A67E40B32864A93C508924024781C792EF8E82DDA7D0C4)

[on('windowStatusChange')](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#onwindowstatuschange11)和[on('windowStatusDidChange')](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#onwindowstatusdidchange20)均在窗口windowStatus发生变化时进行通知，[on('windowStatusChange')](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#onwindowstatuschange11)不保证回调发生时窗口属性更新完成，应用若需要在收到windowStatus变化通知时能够立即获取到变化后的窗口大小、位置，建议使用[on('windowStatusDidChange')](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#onwindowstatusdidchange20)。

#### 如何设置全局悬浮窗背景色为透明

可以通过调用[setWindowBackgroundColor](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setwindowbackgroundcolor9)接口，传入'#00XXXXXX'（其中X代表任意十六进制数字）或者透明的[ColorMetrics](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-arkui-graphics#colormetrics12)实现窗口背景透明。

#### 如何判断应用被部分遮挡或完全遮挡

目前要判断当前窗口是否被遮挡有两个接口：

*   [on('windowVisibilityChange')](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#onwindowvisibilitychange11)：监听窗口可见性，当回调为false时，表示当前窗口不可见，完全被遮挡；当回调返回true时，表示当前窗口可见，但不能区分是部分遮挡还是无遮挡。
    
*   [on('occlusionStateChanged')](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#onocclusionstatechanged22)：监听窗口可见性，返回三种可见状态：无遮挡（表示完全可见，值为0）、部分遮挡（表示部分可见，值为1）、完全遮挡（表示不可见，值为2）。
    

#### 如何判断设备是否开启了自由多窗

可通过[isInFreeWindowMode()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#isinfreewindowmode22)接口查询是否处于自由窗口状态。返回值为true时，表示当前窗口在自由窗口模式，返回值为false时，表示在非自由窗口模式。

可通过[on('freeWindowModeChange')](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#onfreewindowmodechange22)接口监听自由窗口模式变化。

#### 如何设置隐私窗口

可通过[setWindowPrivacyMode](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setwindowprivacymode9-1)接口设置窗口为隐私模式，设置为隐私模式的窗口，窗口内容将无法被截屏或录屏。

对于画中画和闪控球窗口，其隐私模式跟随父窗口。

若需要对隐私窗口进行截图，可使用[snapshotIgnorePrivacy()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#snapshotignoreprivacy18)接口。

#### resize、moveWindowTo等接口有什么位置/大小限制

当调用[resize()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#resize9-1)接口调整窗口大小时，窗口尺寸大小范围会受到[WindowLimits](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-i#windowlimits11)限制，具体尺寸限制范围可以通过[getWindowLimits](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#getwindowlimits11)接口进行查询。

调用[moveWindowTo()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#movewindowto9-1)接口调整窗口位置对窗口位置无限制。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/71/v3/wzmudIaCTEWOsjJNol8EFw/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132330Z&HW-CC-Expire=86400&HW-CC-Sign=727DE7F3D83081430B2099C92112130A66024760644490DA2379CC12E14C611F)

**resize接口其他限制：**

*   在[自由窗口](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/window-terminology#freeform-window自由窗口)状态下，窗口为自由悬浮窗口模式（即窗口模式为window.WindowStatusType.FLOATING，WindowStatusType可通过[getWindowStatus()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#getwindowstatus12)获取）时调用生效，否则抛出错误码1300002。
    
*   在非[自由窗口](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/window-terminology#freeform-window自由窗口)状态下，主窗口调用不生效。
    

**moveWindowTo接口其他限制：**

*   不建议在除自由悬浮窗口模式（即窗口模式为window.WindowStatusType.FLOATING，WindowStatusType可通过[getWindowStatus()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#getwindowstatus12)获取）外的其他窗口模式下使用。
    
*   在[自由窗口](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/window-terminology#freeform-window自由窗口)状态下，窗口相对于屏幕移动；在非自由窗口状态下，窗口相对于父窗口移动。
    
*   若需在非自由窗口状态下实现相对于屏幕的移动，请使用[moveWindowToGlobal()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#movewindowtoglobal15)。
    
*   在非[自由窗口](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/window-terminology#freeform-window自由窗口)状态下，主窗口调用不生效。
    

#### 如何设置或取消水印

*   进程级水印：可通过[setWatermarkImageForAppWindows()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-f#windowsetwatermarkimageforappwindows21)设置或取消应用进程级水印，针对当前应用进程的窗口生效，包括后续该进程新创建的窗口。

#### 如何将创建的窗口移动到扩展屏

*   应用可通过主动调用[moveWindowToGlobal()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#movewindowtoglobal15)接口将当前窗口移动到扩展屏幕，通过配置接口参数中的[MoveConfiguration](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-i#moveconfiguration15)指定当前窗口期望移动的目标屏幕。
    
*   应用也可调用[startMoving()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#startmoving14)接口通过鼠标或触摸点拖拽将当前窗口移动到目标屏幕上。该接口仅在[onTouch](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-events-touch#ontouch)事件（其中，事件类型必须为TouchType.Down）的回调方法中调用才会有移动效果，成功调用此接口后，窗口将跟随鼠标或触摸点移动。
    

#### 子窗口背景如何实现半透明效果

子窗口可以调用[setWindowBackgroundColor](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setwindowbackgroundcolor9)接口，传入'#XXYYYYYY'（其中XX代表任意十六进制且不为0数值，Y表示任意十六进制数字）或者半透明的[ColorMetrics](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-arkui-graphics#colormetrics12)。

示例代码如下所示：

import { BusinessError } from '@kit.BasicServicesKit';
import { ColorMetrics } from '@kit.ArkUI';
import { window } from '@kit.ArkUI';

let storage: LocalStorage = new LocalStorage();
storage.setOrCreate('storageSimpleProp', 121);
windowClass.loadContent("pages/page2", storage, (err: BusinessError) => {
  let errCode: number = err.code;
  if (errCode) {
  console.error(\`Failed to load the content. Cause code: ${err.code}, message: ${err.message}\`);
  return;
  }
  console.info('Succeeded in loading the content.');
  let color1: string = '#8800FF33'; // 采用ARGB方式
  let color2: ColorMetrics = ColorMetrics.numeric(0x88112233);  // 采用ColorMetrics方式
  try {
    windowClass?.setWindowBackgroundColor(color1);
    windowClass?.setWindowBackgroundColor(color2);
  } catch (exception) {
    console.error(\`Failed to set the background color. Cause code: ${exception.code}, message: ${exception.message}\`);
  };
});

#### 如何设置页面级亮度

当前不支持设置页面级亮度，仅支持设置窗口级亮度。

应用若想实现页面级亮度调整，可以在进入特定页面时在主窗调用[setWindowBrightness()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setwindowbrightness9-1)调整亮度，在退出特定页面时，在主窗调用[setWindowBrightness()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setwindowbrightness9-1)传入-1，恢复为系统屏幕亮度。

#### 如何恢复系统屏幕亮度

针对Phone、Tablet设备，应用可以调用[setWindowBrightness()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setwindowbrightness9-1)传入-1，即可恢复为系统屏幕亮度。

针对PC/2in1设备，由于窗口亮度和系统亮度已实现归一化，故调用[setWindowBrightness()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setwindowbrightness9-1)接口后将直接改变系统亮度，目前尚无恢复至调用前窗口亮度的方法。

#### 如何正常获取顶层窗口

**问题现象**

当使用[getLastWindow()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-f#windowgetlastwindow9)获取应用最顶层窗口时，获取到了正在销毁的子窗。

**产生原因**

当使用[destroyWindow()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#destroywindow9)销毁子窗时，未等待其销毁完成即调用[getLastWindow()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-f#windowgetlastwindow9)，导致获取到了正在销毁的子窗。

**解决措施**

在使用[getLastWindow()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-f#windowgetlastwindow9)获取应用最顶层窗口前，应确保子窗销毁、窗口创建等操作已完成。

**示例代码**

import { BusinessError } from '@kit.BasicServicesKit';
import { window } from '@kit.ArkUI';

let lastWindow: window.Window | undefined = undefined;
// 不建议写法
try {
  // 请先获取window实例
  windowClass.destroyWindow();
  try {
    window.getLastWindow(this.context).then((topWindow) => {
      lastWindow = topWindow;
    }).catch((err: BusinessError) => {
      console.error(\`Failed to obtain the last window. Cause code: ${err.code}, message: ${err.message}\`);
    });
  } catch (exception) {
    console.error(\`Failed to obtain the last window. Cause code: ${exception.code}, message: ${exception.message}\`);
  }
} catch (exception) {
  console.error(\`Failed to destroy. Cause code: ${exception.code}, message: ${exception.message}\`);
};

// 建议写法
try {
  // 请先获取window实例
  windowClass.destroyWindow().then(() => {
    try {
      window.getLastWindow(this.context).then((topWindow) => {
        lastWindow = topWindow;
      }).catch((err: BusinessError) => {
        console.error(\`Failed to obtain the last window. Cause code: ${err.code}, message: ${err.message}\`);
      });
    } catch (exception) {
      console.error(\`Failed to obtain the last window. Cause code: ${exception.code}, message: ${exception.message}\`);
    }
  }).catch((err: BusinessError) => {
    console.error(\`Failed to destroy the window. Cause code: ${err.code}, message: ${err.message}\`);
  });
} catch (exception) {
  console.error(\`Failed to destroy. Cause code: ${exception.code}, message: ${exception.message}\`);
};

#### getWindowProperties接口返回值中的窗口类型（type字段）不符合预期

**问题现象**

因为历史问题，主窗场景调用[getWindowProperties()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#getwindowproperties9)获取到的窗口类型即[WindowType](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-e#windowtype7)为TYPE\_SYSTEM\_ALERT而不是TYPE\_MAIN。

**解决措施**

系统的后续API版本中将提供新的字段修正。

应用内创建窗口时需要指明窗口类型，开发者可以直接感知窗口类型，不必要通过此接口主动获取。

#### on('windowSizeChange')等监听回调中通过getWindowAvoidArea()接口获取到的避让区域数据不是最新的

**问题现象**

在[on('windowSizeChange')](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#onwindowsizechange7)、[on('windowRectChange')](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#onwindowrectchange12)等窗口属性变化监听回调中，通过[getWindowAvoidArea()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#getwindowavoidarea9)接口获取到的避让区域数据不准确。

**产生原因**

避让区域更新同时依赖窗口位置/尺寸属性的更新和系统界面元素（如状态栏）的位置/尺寸更新，在窗口属性更新回调触发时系统界面元素不一定已完成更新，这个时候通过getWindowAvoidArea()接口不能拿到准确的避让区域。

**解决措施**

通过避让区域专有的监听接口[on('avoidAreaChange')](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#onavoidareachange9)监听避让区域变化，避免在其他窗口属性变化事件回调中通过getWindowAvoidArea()接口主动获取避让区域。

**示例代码**

import { window } from '@kit.ArkUI';

// 代码中假设windowClass为已获取的Window实例

// 错误写法：监听windowSizeChange事件主动获取避让区域
windowClass.on('windowSizeChange', () => {
  try {
    const systemAvoidArea = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE\_SYSTEM);  // 获取到的避让区域不准确
  } catch (exception) {
    console.error(\`Failed to get window avoid area. Cause code: ${exception.code}, message: ${exception.message}\`);
  }
});

// 正确写法：监听avoidAreaChange事件
windowClass.on('avoidAreaChange', (data) => {
  if (data.type === window.AvoidAreaType.TYPE\_SYSTEM) {
    const systemAvoidArea = data.area;  // 回调中的数据总是准确的避让区域
  }
});