“编译通过了,迁移完成了。”——错。
为什么那么多人在把 React Native 应用的目标 SDK 从 35 升到 36(也就是 Android 16)后,界面突然变得面目全非?明明只是一个 Gradle 参数的修改,但测试一跑,状态栏吃掉了标题,缺口压住了按钮,登录页像是被谁推倒了重来。
这事真正棘手的部分,恰恰不在构建脚本,而在于一次 SDK 升级实际触发了一场“行为迁移”。
我们把 compileSdkVersion 和 targetSdkVersion 从 35 升到 36,顺带把 Android Gradle Plugin 从 8.7.x 提到 8.9.1+,Gradle 从 8.9 上到 8.11.1+,buildToolsVersion 同步到 36.x——这些数字改完,构建一次性成功。团队里开始有人乐观地下结论:这次升级真简单。然而这个结论忽略了最关键的一个事实:平台版本变了,系统的默认行为也变了,根本没有动过的 JavaScript 代码,突然就和新的渲染规则杠上了。
我们陆续撞上的症状包括:页面头部藏进了状态栏底下、刘海区域的内容被遮挡、返回按钮触摸区变小、输入框的键盘表现异常、表单交互卡顿,甚至连一些以前不易察觉的导航问题也一下子暴露出来。它们全都没有经过任何代码变更,纯粹是目标 SDK 提升后,Android 系统对窗口绘制的假设被推翻了。
所以我们的处理策略非常明确:不要和 RN 大版本升级、导航重写、UI 翻新甚至安全区全面重构混在一起。先让平台迁移通过,再专心修补这次迁移暴露出来的平台特有行为问题。这听起来很克制,但恰恰是避免“改动像多米诺骨牌一样蔓延”的唯一方式。
整个迁移中最让人措手不及的,是 Android 强制启用的“边到边”显示。在 Android 16 上,windowOptOutEdgeToEdgeEnforcement 已经不再是一个靠谱的退路,系统不再替你的界面预留状态栏下方的空间了。这意味着过去 React Native 应用里一个普遍存在的隐形假设——“系统会自动把我的内容推到状态栏下面”——彻底失效。现在,你的界面可以尽情绘制到系统栏的背后,前提是你本身就为这种全屏布局做过设计;但如果你的 UI 一直依赖系统帮你避开状态栏,那就直接翻车。
第一波问题就是:标题栏被裁掉一半,下巴伸进了刘海区域,登录页看起来像是排版错乱的草稿。尝试修复时,稍不小心就让空白区变得异常巨大,整个界面松松散散,完全失去原本的紧凑感。
见到这类问题,很多人的本能反应是给每个页面补安全区。别这么干。
如果你的导航容器已经在处理顶部的 inset,而每个页面又各自加了一层安全区 padding,结果就是:双层留白、大块空洞、标题对不齐、间距全乱套。这种逐屏修补的思路,很快会制造出比一开始更棘手的视觉 bug。
在我们的架构里,真正管用的做法是把 Android 顶部 inset 的应用位置收敛到一处:在根路由或导航容器上统一处理一次,而不是在每个页面重复这一逻辑。这样既能保证所有页面共享一致的偏移量,也不会出现因重复叠加而产生的多余空白。迁移之后,再针对具体的页面细节做微调,远比一开始就四处贴补丁高效得多。
所以,如果你正在规划 React Native Android 应用的目标 SDK 升级,且 Google Play 要求在 2026 年 8 月 31 日之后所有应用更新都必须面向 Android 16,别再把这次迁移简单理解成 build.gradle 里的几个数字变化。它本质上是对你的 UI 如何与系统栏共存的一次全面检验。先用最小的改动完成平台合规,再集中处理边到边带来的布局冲击,你的进度条才不会一次次退回原点。
热门跟贴