HarmonyOS 鸿蒙Next中通过windowInsets实现刘海屏/挖孔屏安全区域适配
HarmonyOS 鸿蒙Next中通过windowInsets实现刘海屏/挖孔屏安全区域适配 通过windowInsets实现刘海屏/挖孔屏安全区域适配
实现思路
- 导入 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实现刘海屏、挖孔屏等异形屏的安全区域适配是确保应用界面不被遮挡的关键。以下是核心方法:
-
获取WindowInsets:通过
getWindow().getWindowInsets()获取窗口的Insets信息,其中包含了系统栏(状态栏、导航栏)以及刘海等不可显示区域的边界信息。 -
使用安全区域:重点关注
WindowInsets中的getDisplayCutout()方法,它返回一个DisplayCutout对象,包含了刘海或挖孔区域的具体位置和形状。可以通过getSafeInsetTop()、getSafeInsetBottom()等方法获取各方向的安全内边距。 -
应用安全边距:在布局时,将获取到的安全内边距设置为对应视图(如根布局)的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; }); -
全屏处理:如果应用需要全屏显示,可通过
WindowManager.LayoutParams设置LAYOUT_IN_DISPLAY_CUTOUT_MODE属性,控制内容如何与刘海区域交互。例如,LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES允许内容延伸到短边的刘海区域。 -
动态适配:在窗口变化(如旋转屏幕)时重新计算安全区域,通过监听
OnApplyWindowInsetsListener确保实时更新。
注意:测试时需使用模拟器或真机验证不同异形屏的适配效果,确保UI布局的完整性和可用性。

