悬浮窗模式，应用页面未避让顶部窗口控制条
====================

#### 问题现象

应用在悬浮窗模式下，页面是沉浸式布局，但是未注意悬浮窗模式时，顶部存在的窗口控制条，页面顶部内容与悬浮窗的顶部窗口控制条重叠。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/50/v3/I088BZZpRRmCOCmKAFqBjg/zh-cn_image_0000002628766426.png?HW-CC-KV=V1&HW-CC-Date=20260709T134007Z&HW-CC-Expire=86400&HW-CC-Sign=C24600B85CB7B78C909B77C262199B26B50056575EB9DCCE36C64872F9D42B9D "点击放大")

#### 背景知识

*   [setWindowLayoutFullScreen](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-window#setwindowlayoutfullscreen9)：可设置窗口布局是否为沉浸式布局。
*   [顶部窗口控制条](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/multi-window-controlbar-adapt)：顶部窗口控制条是应用窗口处于智慧多窗模式下，应用顶部的操作横条。
*   [沉浸式布局](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-multi-device-window-immersive)是指应用布局不避让状态栏、导航栏以及智慧多窗顶部横条，这可能发生组件与顶部横条的重叠，导致文字遮挡、点击事件冲突等情况。
*   [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)：开启当前应用窗口系统避让区变化的监听。

#### 问题定位

1.  查阅代码中是否调用setWindowLayoutFullScreen接口并设置为true。
    
    windowClass.setWindowLayoutFullScreen(true)
    
2.  查阅代码中是否调用getWindowAvoidArea获取系统默认区域的高度（通常表示状态栏区域，悬浮窗状态下的应用主窗中表示顶部窗口控制条区域）。
    
    this.topSafeHeight = this.getUIContext().px2vp(windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE\_SYSTEM).topRect.height)
    
3.  查阅代码中是否调用on('avoidAreaChange')监听系统默认区域高度的变化。
    
    windowClass.on('avoidAreaChange', (data) => {
      if (data.type == window.AvoidAreaType.TYPE\_SYSTEM) {
        this.topSafeHeight = this.getUIContext().px2vp(data.area.topRect.height)
      }
    })
    
4.  查阅代码中是否设置padding进行顶部避让。
    
    build() {
      Stack({ alignContent: Alignment.TopStart }) {
       ** // 顶部避让区域**
        Row() {
        }
        .padding({top:this.topSafeHeight})
        .width("100%")    
      }
      .height('100%')
    }
    

#### 分析结论

应用代码中调用了setWindowLayoutFullScreen接口，打开了窗口沉浸式，故应用不会自动避让状态栏或者三点功能栏，而应用中未调用avoidAreaChange接口监听系统默认区域高度变化，动态配置顶部避让区域，导致悬浮窗场景下，页面内容未避让顶部窗口控制条。

#### 修改建议

应用开启沉浸式布局后，可以通过getWindowAvoidArea接口可获取屏幕顶部需要避让的矩阵区域topRect，获取到该值后应用可对应使用padding进行布局避让，并且注册on('avoidAreaChange')监听系统避让区域变化以进行布局的动态调整。

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


@Entry
@Component
struct topSafePage {
  @State topSafeHeight: number = 0;


  getWindow(): window.Window {
    let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
    let windowStage = context.windowStage;
    let windowClass = windowStage.getMainWindowSync();
    return windowClass;
  }


  aboutToAppear(): void {
    let windowClass: window.Window = this.getWindow();
    this.topSafeHeight =
      this.getUIContext().px2vp(windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE\_SYSTEM).topRect.height);
    windowClass.setWindowLayoutFullScreen(true);
    windowClass.on('avoidAreaChange', (data) => {
      if (data.type === window.AvoidAreaType.TYPE\_SYSTEM) {
        this.topSafeHeight = this.getUIContext().px2vp(data.area.topRect.height);
      }
    });
  }


  build() {
    Column() {
      Row() {
        _// 内容区域_
        Text('进行顶部三点区域避让');
      }
      .width('100%')
      .justifyContent(FlexAlign.Center);
    }
 _   // 使用padding进行避让_
    .padding({ top: this.topSafeHeight });
  }
}