Android API35升级后XML配置的Window inset edge-to-edge不符合预期,需恢复API34时标题栏不与状态栏重叠的原有行为
我太懂你升级到API 35后的糟心感受了——原本在API 34里标题规规矩矩待在状态栏下方,结果一升级直接和状态栏重叠,而且你还不想用android:windowLayoutInDisplayCutoutMode="never"这种临时凑活的方案,试过代码禁用也没效果对吧?
别着急,咱们一步步来解决这个问题:
1. 先调整主题配置(最直接的方法)
API 35里默认的windowDecorFitsSystemWindows属性值可能发生了变化,导致系统默认让内容延伸到状态栏下方。你可以在themes.xml的主题里添加这个属性,强制让布局适配系统窗口:
<style name="YourAppTheme" parent="Theme.Material3.DayNight.NoActionBar"> <!-- 其他主题属性 --> <item name="android:windowDecorFitsSystemWindows">true</item> </style>
这个属性设置为true后,系统会自动帮你调整布局,避免内容跑到状态栏或者导航栏的区域里,应该能快速恢复API 34时的行为。
2. 代码层面手动处理Window Insets(如果主题调整没生效)
如果主题设置后还是有问题,那可以手动给标题栏(比如Toolbar或者AppBarLayout)设置Insets监听,主动给标题栏加上状态栏高度的padding:
Kotlin示例
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_home) val toolbar = findViewById<Toolbar>(R.id.toolbar) ViewCompat.setOnApplyWindowInsetsListener(toolbar) { view, insets -> // 获取状态栏的Insets val statusBarInsets = insets.getInsets(WindowInsetsCompat.Type.statusBars()) // 给Toolbar设置顶部padding,避让状态栏 view.setPadding(view.paddingLeft, statusBarInsets.top, view.paddingRight, view.paddingBottom) insets } }
Java示例
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); Toolbar toolbar = findViewById(R.id.toolbar); ViewCompat.setOnApplyWindowInsetsListener(toolbar, (view, insets) -> { Insets statusBarInsets = insets.getInsets(WindowInsetsCompat.Type.statusBars()); view.setPadding(view.getPaddingLeft(), statusBarInsets.top, view.getPaddingRight(), view.getPaddingBottom()); return insets; }); }
这里要注意,别用已经废弃的systemUiVisibility相关方法,WindowInsetsCompat是API 21+都兼容的正确处理方式。
3. 检查是否有代码强制开启了Edge-to-Edge
如果你之前的代码里调用过WindowCompat.setDecorFitsSystemWindows(window, false),这行代码会强制让内容延伸到系统栏下方,记得把它改成true或者直接删掉这行代码,否则上面的设置都会被覆盖。
另外,如果你的布局里用了AppBarLayout,记得给它加上android:fitsSystemWindows="true"属性,这样它会自动适配状态栏的高度,不用额外处理。
试完这些步骤,应该就能让标题栏回到API 34时乖乖待在状态栏下方的状态啦!
备注:内容来源于stack exchange,提问作者Ishika Singh

