HarmonyOS 鸿蒙Next中通过windowInsets实现刘海屏/挖孔屏安全区域适配

HarmonyOS 鸿蒙Next中通过windowInsets实现刘海屏/挖孔屏安全区域适配 通过windowInsets实现刘海屏/挖孔屏安全区域适配

3 回复

实现思路

  • 导入 window 模块并声明 insets 状态
import window from '@ohos.window';
@State topInset: number = 0; // 状态栏高度
@State bottomInset: number = 0; // 导航栏高度
  • 在 aboutToAppear 中获取当前窗口并监听 insets 变化
aboutToAppear() {
  let windowClass: window.Window;
  window.findWindowByName('main').then(win => {
    windowClass = win;
    // 获取初始 insets
    const insets = windowClass.getWindowInsets();
    this.topInset = insets.statusBarHeight;
    this.bottomInset = insets.navigationBarHeight;

    // 监听 insets 变化(如横竖屏切换、分屏)
    windowClass.on('windowInsetsChanged', (newInsets) => {
      this.topInset = newInsets.statusBarHeight;
      this.bottomInset = newInsets.navigationBarHeight;
    });
  });
}
  • 在 UI 布局中应用安全边距
Column() {
  Text('重要操作按钮')
    .padding(15)
    .backgroundColor('#4A90E2')
    .fontColor(Color.White)
}
.padding({
  top: this.topInset,      // 避开状态栏
  bottom: this.bottomInset // 避开导航栏
})

完整代码

import window from '@ohos.window';

@Entry
@Component
struct SafeAreaDemo {
  @State topInset: number = 0;
  @State bottomInset: number = 0;

  aboutToAppear() {
    window.findWindowByName('main').then(win => {
      const insets = win.getWindowInsets();
      this.topInset = insets.statusBarHeight;
      this.bottomInset = insets.navigationBarHeight;

      win.on('windowInsetsChanged', (newInsets) => {
        this.topInset = newInsets.statusBarHeight;
        this.bottomInset = newInsets.navigationBarHeight;
      });
    }).catch(err => {
      console.error('[SafeArea] 获取窗口失败:', err);
    });
  }

  build() {
    Column() {
      // 顶部内容(避开状态栏)
      Text('顶部标题')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .width('100%')
        .textAlign(TextAlign.Center)
        .padding({ top: 10, bottom: 10 })
        .backgroundColor('#F0F0F0')

      // 中间内容
      Text('主要内容区域\n不会被挖孔或状态栏遮挡')
        .margin({ top: 30 })
        .fontSize(16)

      // 底部操作按钮(避开导航栏)
      Button('确认操作')
        .width('80%')
        .height(50)
        .margin({ top: 20 })
        .backgroundColor('#4A90E2')
        .fontColor(Color.White)
    }
    .padding({
      top: this.topInset,
      bottom: this.bottomInset,
      left: 16,
      right: 16
    })
    .width('100%')
    .height('100%')
    .backgroundColor('#FFFFFF')
  }
}

更多关于HarmonyOS 鸿蒙Next中通过windowInsets实现刘海屏/挖孔屏安全区域适配的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,使用windowInsets获取安全区域。通过getWindow().getWindowInsets()获取WindowInsets对象,再调用getDisplayCutout()得到挖孔区域信息。getSafeInsets()返回安全边距,getBoundingRects()获取挖孔具体位置。在UI布局时,将关键内容避开这些区域即可适配。

在HarmonyOS Next中,通过windowInsets实现刘海屏、挖孔屏等异形屏的安全区域适配是确保应用界面不被遮挡的关键。以下是核心方法:

  1. 获取WindowInsets:通过getWindow().getWindowInsets()获取窗口的Insets信息,其中包含了系统栏(状态栏、导航栏)以及刘海等不可显示区域的边界信息。

  2. 使用安全区域:重点关注WindowInsets中的getDisplayCutout()方法,它返回一个DisplayCutout对象,包含了刘海或挖孔区域的具体位置和形状。可以通过getSafeInsetTop()getSafeInsetBottom()等方法获取各方向的安全内边距。

  3. 应用安全边距:在布局时,将获取到的安全内边距设置为对应视图(如根布局)的padding或margin,确保关键内容(如标题、按钮)显示在安全区域内。例如:

    View decorView = getWindow().getDecorView();
    decorView.setOnApplyWindowInsetsListener((v, insets) -> {
        DisplayCutout cutout = insets.getDisplayCutout();
        if (cutout != null) {
            int safeInsetTop = cutout.getSafeInsetTop();
            v.setPadding(v.getPaddingLeft(), safeInsetTop, v.getPaddingRight(), v.getPaddingBottom());
        }
        return insets;
    });
    
  4. 全屏处理:如果应用需要全屏显示,可通过WindowManager.LayoutParams设置LAYOUT_IN_DISPLAY_CUTOUT_MODE属性,控制内容如何与刘海区域交互。例如,LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES允许内容延伸到短边的刘海区域。

  5. 动态适配:在窗口变化(如旋转屏幕)时重新计算安全区域,通过监听OnApplyWindowInsetsListener确保实时更新。

注意:测试时需使用模拟器或真机验证不同异形屏的适配效果,确保UI布局的完整性和可用性。

回到顶部