开启Edge-to-Edge后BottomAppBar高度异常增大的原因与解决方法
问题场景
按照Android官方Edge-to-Edge适配规范开发,调用WindowCompat.setDecorFitsSystemWindows(getWindow(), false)开启全屏体验后,BottomAppBar的高度明显变大。布局采用BottomAppBar嵌套BottomNavigationView,配合居中的FloatingActionButton实现底部导航。
原因分析
当关闭decorFitsSystemWindows后,系统不再自动处理布局与系统栏的间距,但Material组件库的BottomAppBar默认会检测系统导航栏的存在,自动添加底部内边距(paddingBottom)来避免自身内容被导航栏遮挡,这就导致BottomAppBar的实际高度被额外的内边距撑大。
解决方法
方法一:禁用BottomAppBar的系统窗口适配(推荐)
直接给BottomAppBar添加android:fitsSystemWindows="false"属性,阻止它自动添加适配系统栏的内边距。这样BottomAppBar会保持原本的高度,同时我们可以通过Edge-to-Edge的逻辑自行管理内容与系统栏的关系。
修改后的BottomAppBar代码片段:
<com.google.android.material.bottomappbar.BottomAppBar android:backgroundTint="#ff0000" app:fabCradleRoundedCornerRadius="0dp" android:layout_gravity="bottom" android:id="@+id/bottom_app_bar" android:layout_width="match_parent" android:layout_height="wrap_content" android:fitsSystemWindows="false"> <!-- 添加此行 --> <!-- 内部的BottomNavigationView保持不变 --> </com.google.android.material.bottomappbar.BottomAppBar>
方法二:动态移除BottomAppBar的底部内边距
如果需要保留部分适配逻辑,可以通过代码动态清除BottomAppBar自动添加的底部内边距:
// 在Activity的onCreate方法中调用 val bottomAppBar = findViewById<BottomAppBar>(R.id.bottom_app_bar) bottomAppBar.setPadding( bottomAppBar.paddingLeft, bottomAppBar.paddingTop, bottomAppBar.paddingRight, 0 // 强制设置底部内边距为0 )
方法三:调整主内容区域的内边距
确保页面主内容(NavHostFragment)不会被BottomAppBar和系统导航栏遮挡,可给主内容容器添加底部内边距,值为BottomAppBar高度加上系统导航栏高度:
// 工具方法:获取系统导航栏高度 private fun getNavigationBarHeight(context: Context): Int { val resources = context.resources val resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android") return if (resourceId > 0) resources.getDimensionPixelSize(resourceId) else 0 } // 在Activity中设置主内容区域内边距 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val mainContent = findViewById<FrameLayout>(R.id.toolbar_content_and_background_image_frame_layout) val bottomAppBarHeight = resources.getDimensionPixelSize(R.dimen.design_bottom_app_bar_height) val navBarHeight = getNavigationBarHeight(this) mainContent.setPadding( mainContent.paddingLeft, mainContent.paddingTop, mainContent.paddingRight, bottomAppBarHeight + navBarHeight ) }
总结
方法一最为简洁高效,直接切断BottomAppBar的自动适配逻辑,符合Edge-to-Edge开发中手动管理布局与系统栏关系的原则,推荐优先使用。
内容的提问来源于stack exchange,提问作者Cheok Yan Cheng

