Android Material3应用修改状态栏透明度致BottomNavigationView高度异常
问题核心是WindowCompat.setDecorFitsSystemWindows(window, false)会改变Activity窗口的布局适配规则,导致BottomNavigationView的布局计算被干扰。即使返回时恢复了true,也可能因为Fragment生命周期的时序问题,没有及时触发布局重绘。下面是几种可行的解决方法:
方法一:在Fragment生命周期中及时恢复窗口状态
在DetailFragment的销毁回调里,主动恢复窗口的适配状态,确保回到前一个Fragment时,Activity的窗口规则已经正确重置,同时强制触发布局重绘:
class DetailFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) requireActivity().transparentStatusBar(true) } override fun onDestroyView() { super.onDestroyView() requireActivity().transparentStatusBar(false) // 强制BottomNavigationView重新计算布局 requireActivity().findViewById<BottomNavigationView>(R.id.bottom_nav)?.requestLayout() } }
方法二:保留DecorFitsSystemWindows为true,仅修改状态栏颜色
如果不需要布局延伸到状态栏下方,只是要状态栏透明,可以去掉setDecorFitsSystemWindows的设置,直接修改状态栏颜色,这样不会干扰整个Activity的布局规则:
修改你的transparentStatusBar函数:
fun Activity.transparentStatusBar(transparent: Boolean) { // 始终保持系统布局适配规则,避免全局布局混乱 WindowCompat.setDecorFitsSystemWindows(window, true) if (transparent) { window.statusBarColor = Color.TRANSPARENT // 可选:根据背景色调整状态栏文字明暗 WindowInsetsControllerCompat(window, window.decorView).isAppearanceLightStatusBars = true } else { window.statusBarColor = Color.parseColor("#F8FDFF") WindowInsetsControllerCompat(window, window.decorView).isAppearanceLightStatusBars = false } }
方法三:给BottomNavigationView固定适配系统inset
如果必须使用setDecorFitsSystemWindows(false),可以通过监听窗口inset来给BottomNavigationView添加正确的底部padding,避免高度异常:
在包含BottomNavigationView的Activity或父Fragment中添加:
val bottomNav = findViewById<BottomNavigationView>(R.id.bottom_nav) ViewCompat.setOnApplyWindowInsetsListener(bottomNav) { view, insets -> val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) view.setPadding(0, 0, 0, systemBars.bottom) insets }
这样即使窗口布局规则改变,BottomNavigationView也会根据系统inset自动调整底部padding,保持正确的显示高度。
内容的提问来源于stack exchange,提问作者Noah
相关产品推荐
相关产品推荐

