非常好的问题 👍。 “窗口 Insets(WindowInsets)” 不是 Android 15 才有的东西——它其实早在 Android 10(API 29) 之前就出现了,但到了 Android 11–15,它被彻底取代了老的布局适配机制,变得非常重要。
WindowInsets 表示的是 系统窗口(System Windows)占用的区域信息,比如:
区域 | 示例 | 说明 |
|---|---|---|
状态栏(Status bar) | 屏幕上方时间/信号栏 | 内容不要绘制到这里 |
导航栏(Navigation bar) | 底部三键 / 手势区域 | 触控手势、返回键等区域 |
键盘(IME) | 软键盘弹出时 | 会遮挡输入框 |
Display cutout(刘海/挖孔) | notch 区域 | 需要避开 |
👉 简单理解:
WindowInsets 告诉应用:哪些地方被系统 UI 占用了,你的内容该怎么避开它们。
在旧的 Android 版本(比如 Android 5–8)里,我们用:
fitSystemWindows
systemUiVisibility
android:fitsSystemWindows="true"
来让内容避开状态栏或导航栏。
但这些方法非常不灵活:
问题 | 旧方案 | WindowInsets 解决方式 |
|---|---|---|
状态栏、导航栏尺寸不固定 | 需要硬编码或不同设备适配 | 动态计算 Insets |
全屏 + 手势冲突 | 不同 ROM 表现不一致 | 官方统一 API |
键盘遮挡输入框 | 需要监听键盘高度 | 直接通过 Insets 获取 IME 区域 |
刘海屏、圆角屏适配 | 手动判断 cutout 区域 | 通过 DisplayCutoutInsets 自动提供 |
多窗口 / 分屏 | 旧 API 失效 | Insets 自动更新可见区域 |
android:fitsSystemWindows="true"ViewCompat.setOnApplyWindowInsetsListener(view) { v, insets ->
val systemBarsInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBarsInsets.left, systemBarsInsets.top,
systemBarsInsets.right, systemBarsInsets.bottom)
insets
}👉 这样无论是全屏、刘海屏、手势导航,还是键盘弹出,布局都能自动避开系统区域。
在 Android 15 中:
ViewRootImpl、DecorView 直接迁移为 InsetsController 控制。
换句话说: Android 15 更彻底地让 WindowInsets 成为唯一的系统安全绘制边界机制, 所有窗口绘制逻辑(状态栏、导航栏、手势区域)都通过它管理。
概念 | 含义 |
|---|---|
WindowInsets | 系统窗口占用的安全区域信息 |
用途 | 让布局避开状态栏、导航栏、键盘、刘海等区域 |
解决问题 | 统一适配、自动避让、兼容多形态设备 |
Android 15 特点 | 完全过渡到 Insets 框架,取代老的 fitsSystemWindows 体系 |
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。