切换Fragment时Window Insets状态未恢复,仅单个Fragment需设置透明状态栏
问题根源
- 调用
hideStatusBar时给根布局绑定的OnApplyWindowInsetsListener没有在切换Fragment时移除,该监听返回WindowInsetsCompat.CONSUMED会消费所有窗口边距信息,导致其他Fragment无法获取状态栏高度完成布局适配。 showStatusBar方法错误保留了状态栏透明配置,未恢复为正常状态栏颜色。- 切换回普通Fragment时,没有重置根布局之前被修改的边距参数,也没有触发窗口边距重新分发,导致布局位置异常。
修复方案
1. 修正showStatusBar实现
private fun showStatusBar() { // 替换为你应用正常状态下的状态栏颜色值 window.statusBarColor = ContextCompat.getColor(this@SuperActivity, R.color.your_app_primary_status_color) // 移除之前设置的窗口边距监听,停止消费边距信息 ViewCompat.setOnApplyWindowInsetsListener(binding.root, null) // 重置根布局边距为初始值,若你的根布局有默认边距可提前存储初始值再恢复 binding.root.updateLayoutParams<ViewGroup.MarginLayoutParams> { leftMargin = 0 rightMargin = 0 bottomMargin = 0 } // 恢复系统窗口适配逻辑 WindowCompat.setDecorFitsSystemWindows(window, true) // 主动触发窗口边距重新分发,确保状态立即生效 ViewCompat.requestApplyInsets(binding.root) }
2. 优化切换逻辑
在底部导航选中回调中,每次切换前先调用showStatusBar重置全局窗口状态,再判断当前选中的Fragment是否需要透明状态栏,是的话再调用hideStatusBar,避免状态残留:
bottomNav.setOnItemSelectedListener { item -> // 先重置为默认状态栏状态 showStatusBar() when(item.itemId) { R.id.nav_transparent_fragment -> { hideStatusBar() // 切换到对应Fragment逻辑 } // 其他导航项处理 } true }
可选优化
建议将透明状态栏的适配逻辑下沉到对应Fragment内部:在Fragment的onStart生命周期调用透明状态栏逻辑,onStop生命周期调用恢复逻辑,和Activity解耦,避免多Fragment切换时的状态冲突。
内容的提问来源于stack exchange,提问作者Taha Asif
相关产品推荐
相关产品推荐

