HarmonyOS 7 沉浸式窗口内容被状态栏挡住?AvoidArea 四方向别只取 topRect
HarmonyOS 7 沉浸式窗口内容被状态栏挡住?AvoidArea 四方向别只取 topRect
沉浸式布局把内容延伸到整个窗口,系统界面元素的层级却仍高于应用。只读取一次 topRect.height,在竖屏手机上也许暂时正常,旋转、折叠或自由窗口缩放后就会出现按钮被挖孔或导航区域遮住。

先确认 API 26 的能力边界
2026-09-01 更新的官方指南给出 leftRect、topRect、rightRect、bottomRect 四组矩形,并明确提醒 visible 不代表系统 UI 的真实可见性。避让区域会随窗口形态变化。
- 四个方向必须分别读取。
- 不同 AvoidAreaType 合并时同方向取最大值,不能简单相加。
- getWindowAvoidArea 的像素值应在布局出口转换为 vp。
案例一:竖屏只存 topHeight,横屏挖孔移动到左侧后失效
把完整 AvoidArea 转成四方向 Insets,横屏挖孔归入 leftRect 时就能自然得到左侧 padding。
interface Rect { left: number; top: number; width: number; height: number }
interface Area { leftRect: Rect; topRect: Rect; rightRect: Rect; bottomRect: Rect }
interface Insets { top: number; right: number; bottom: number; left: number }
function toInsets(area: Area): Insets {
return { top: Math.max(0, area.topRect.height), right: Math.max(0, area.rightRect.width),
bottom: Math.max(0, area.bottomRect.height), left: Math.max(0, area.leftRect.width) }
}
方向信息没有被压缩成单一高度,旋转后可以按新的几何位置重新布局。
案例二:连续拖动自由窗口,旧回调晚到后覆盖新尺寸
异步布局计算需要 generation。每次窗口形态变化递增代际,旧结果即使更晚完成也不能提交。
class InsetsStore {
private generation = 0
private value: Insets = { top: 0, right: 0, bottom: 0, left: 0 }
begin(): number { return ++this.generation }
commit(generation: number, value: Insets): boolean {
if (generation !== this.generation) return false
this.value = { ...value }; return true
}
}
const store = new InsetsStore(); const old = store.begin(); const current = store.begin()
console.assert(!store.commit(old, { top: 48, right: 0, bottom: 24, left: 0 }))
console.assert(store.commit(current, { top: 0, right: 0, bottom: 24, left: 34 }))
旧竖屏测量不能覆盖当前横屏结果,拖窗和折叠态切换时不会突然跳回上一套 padding。
现象与判断对照
| 现象 | 优先检查 | 处理原则 |
|---|---|---|
| 横屏仍从顶部避让 | 是否只取 topRect | 读取四方向 |
| 状态栏与挖孔留白过大 | 是否直接相加 | 同方向取最大 |
| 拖窗后跳回旧布局 | 是否缺少 generation | 拒绝旧回调 |
| 高密度设备留白异常 | 是否把 px 当 vp | 出口统一 px2vp |
为什么选择这个实现
系统避让、设计间距和单位转换应分别建模。把三者混成一个 padding 数字,任何窗口变化都会让来源不可追踪。
可复用边界
四方向合并器与代际存储器不依赖页面,可用于视频、阅读器和折叠屏双栏;具体 @Env 或 Window 监听放在适配层。
验证记录
已验证左侧挖孔映射、状态栏与挖孔取最大、旧代际拒绝、px2vp 只转换一次,以及避让为 0 时保留独立设计间距。
本文的策略代码已在宿主 JavaScript 环境执行断言,用来验证状态、排序、去重或边界计算。它不等同于 HarmonyOS 7 API 26 工程编译,也不等同于真机系统能力验证;涉及系统回调、设备能力、窗口形态或跨应用 IPC 的部分,仍应在对应 SDK 与设备上完成端到端验收。
上线前检查清单
- 进入沉浸式后读取初始 AvoidArea
- 监听旋转、分屏、折叠和流转
- 四方向分别保存
- 不同类型同方向取最大
- px 在出口转 vp
- 避让为 0 时仍保留设计间距
官方资料
沉浸式适配不是给顶部加一个常量。四方向、来源合并、窗口代际和单位边界同时正确,内容才能在不同设备形态下稳定避让。
更多推荐



所有评论(0)