目录

通过createWindow创建子窗口,顶部胶囊的位置异常

问题现象

元服务中,使用createWindow创建子窗口,顶部胶囊位置被状态栏遮挡,具体如下图所示:

背景知识

问题定位

使用createWindow()创建子窗口时,在非自由窗口状态下,子窗口创建后默认是沉浸式布局。沉浸式页面开发通常会将应用页面延伸至状态栏和导航条,进而产生UI元素的遮挡。可以使用getWindowAvoidArea()方法获取避让区域的高度,结合resize()和moveWindowTo()避让状态栏。

分析结论

createWindow()创建子窗口时默认是沉浸式布局。元服务胶囊和状态栏位置产生重叠,需调整页面布局,避免遮挡。

修改建议

使用getWindowAvoidArea()方法获取避让区域的高度,使用resize()重置窗口大小,并使用moveWindowTo()移动窗口位置,具体代码如下:

import { display, window } from '@kit.ArkUI';
import { Context } from '@kit.AbilityKit';

@Entry
@Component
struct Index {
  async createSubWindow() {
    try {
      let context = this.getUIContext().getHostContext() as Context;
      // 当创建窗口类型为window.WindowType.TYPE_FLOAT时需要申请ohos.permission.SYSTEM_FLOAT_WINDOW
      const win = await window.createWindow({
        name: 'sub_window',
        windowType: window.WindowType.TYPE_DIALOG,
        ctx: context,
      });

      await win.setUIContent('pages/SubWindowContent');
      win.setWindowBackgroundColor('#48f65555');
      let displayInfo = display.getDefaultDisplaySync();
      // 获取状态栏高度
      let mainWindow = await window.getLastWindow(context);
      const avoidAreaType = window.AvoidAreaType.TYPE_SYSTEM;
      let avoidArea = mainWindow.getWindowAvoidArea(avoidAreaType);
      let avoidAreaHeight = avoidArea.topRect.height;
      await win.resize(displayInfo.width, displayInfo.height - avoidAreaHeight);
      await win.moveWindowTo(0, avoidAreaHeight);
      await win.setWindowFocusable(true);
      await win.showWindow();
    } catch (e) {
      console.error('create window error:', e);
    }
  }

  build() {
    Column() {
      Button('创建子窗口').onClick(() => this.createSubWindow());
    }.width('100%').height('100%').justifyContent(FlexAlign.Center);
  }
}

子窗口代码:

@Entry
@Component
struct SubWindowContent {
  build() {
    Column() {
      Text('我是子窗口')
        .fontSize(20)
        .margin({ bottom: 20 });
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .backgroundColor('#F5F5F5');
  }
}