Android 35适配异常:edge-to-edge模式下导航栏变黑且内容未延伸至边缘
老哥我太懂这种老项目升级安卓新版本的糟心了!尤其是你这种从2012年就启动的Java+View体系项目,没Compose没Kotlin,升级到API 35遇到这种edge-to-edge的UI问题真的头大。你说的状态栏正常、导航栏变黑且内容没延伸的情况,我之前帮朋友处理过几乎一模一样的,给你捋捋几个大概率能解决的方向:
先查主题配置,别漏了导航栏的关键属性
API 35对导航栏的对比度要求更严格了,默认会强制开启对比色,这就是导航栏变黑的常见原因。打开你的res/values/styles.xml(别忘了v35的values-v35目录下的样式),确保AppTheme里加了这些配置:<!-- 让导航栏透明 --> <item name="android:navigationBarColor">@android:color/transparent</item> <!-- 关闭API 35默认开启的强制导航栏对比色,避免自动变黑 --> <item name="android:enforceNavigationBarContrast">false</item> <!-- 配合旧属性增强兼容性,老项目可能需要这个 --> <item name="android:windowTranslucentNavigation">true</item>另外要确认你的主题继承的是
Theme.Material.Light.NoActionBar这类支持Material设计的主题,旧的Theme.Holo系列在API 35下适配edge-to-edge会有各种奇奇怪怪的问题。代码里要同时处理状态栏和导航栏的edge-to-edge,不能厚此薄彼
你说状态栏正常,大概率是只配置了状态栏的相关代码,没管导航栏。在你的BaseActivity(老项目肯定有统一的BaseActivity吧?)的onCreate方法里,补全导航栏的配置:@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 核心:让内容延伸到系统栏后面,这行不能少! getWindow().setDecorFitsSystemWindows(false); WindowInsetsController insetsController = getWindow().getInsetsController(); if (insetsController != null) { // 状态栏的配置你应该已经加了,比如设置浅色图标 insetsController.setSystemBarsAppearance( WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS, WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS); // 重点!导航栏的图标样式和行为必须设置,不然会触发默认的对比色变黑 insetsController.setSystemBarsAppearance( WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS, WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS); // 如果需要滑动显示隐藏导航栏,也可以加上这行 // insetsController.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE); } }老布局的fitsSystemWindows属性可能在拖后腿
老项目的布局里很多根视图会加android:fitsSystemWindows="true",这个属性会强制视图避开系统栏,直接导致内容无法延伸到导航栏后面。你要把所有相关布局的这个属性改成false,然后用代码动态设置padding,避免内容被系统栏挡住:private void setupEdgeToEdgePadding() { View rootView = findViewById(android.R.id.content); ViewCompat.setOnApplyWindowInsetsListener(rootView, (view, insets) -> { Insets systemInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars()); // 给根布局设置padding,让内容避开状态栏和导航栏 view.setPadding(systemInsets.left, systemInsets.top, systemInsets.right, systemInsets.bottom); return insets; }); }把这个方法在BaseActivity的
onCreate里调用就行,所有子Activity都会生效。排查第三方库的冲突
老项目肯定依赖了不少第三方UI库、沉浸式状态栏库之类的,这些库可能在API 35下没适配edge-to-edge,会偷偷覆盖你的导航栏设置。你可以暂时注释掉这类库的初始化代码,测试一下导航栏是否恢复正常,找到冲突的库后要么升级它的最新版本,要么自己替换掉它的相关功能。
先从主题和Activity的代码配置入手,这两个是最容易踩坑的点,尤其是那个enforceNavigationBarContrast属性,很多人升级API 35都忽略了它,导致导航栏莫名变黑。
备注:内容来源于stack exchange,提问作者Stéphane

