Bottom Navigation View显示异常,求排查问题原因
问题原因分析
这个问题的核心在于你设置的系统UI标志和布局的fitsSystemWindows属性之间的冲突:
- 你在
onResume中添加的SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION和SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN这两个标志,会让Activity的布局延伸覆盖到系统导航栏和状态栏的区域。 - 你的根布局(包含Fragment容器和BottomNavigationView的那个布局)默认大概率设置了
android:fitsSystemWindows="true"(Android Studio的默认模板通常会加上这个)。这个属性的作用是让系统自动给布局添加内边距(padding),避免内容被系统栏遮挡。 - 当你隐藏导航栏后,系统并不会自动移除之前添加的
paddingBottom(因为LAYOUT_HIDE_NAVIGATION标志依然生效),这就导致BottomNavigationView虽然约束到了父布局的底部,但父布局本身离屏幕底部还有一个导航栏高度的内边距,看起来就像是BottomNavigationView“占据了”导航栏的位置,没有紧贴屏幕底部。 - 当你把BottomNavigationView的高度设为55dp时,只是通过固定高度让视觉上更靠近底部,但并没有解决根本的内边距问题。
解决方法
这里有几个可行的方案,你可以根据自己的需求选择:
方案一:关闭根布局的fitsSystemWindows属性
找到你的Activity根布局(应该是ConstraintLayout,因为你用了约束属性),添加android:fitsSystemWindows="false":
<androidx.constraintlayout.widget.ConstraintLayout ... android:fitsSystemWindows="false"> <!-- 你的FrameLayout和BottomNavigationView --> </androidx.constraintlayout.widget.ConstraintLayout>
这样系统就不会自动给根布局添加内边距,BottomNavigationView会直接紧贴屏幕底部。不过要注意:此时Fragment容器的内容会延伸到状态栏和导航栏区域,你需要在Fragment的布局中给顶部/底部添加合适的内边距,避免内容被遮挡。
方案二:动态移除根布局的底部内边距
在设置完系统UI标志后,手动清除根布局的paddingBottom:
@Override public void onResume(){ super.onResume(); View aView = getWindow().getDecorView(); aView.setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); // 获取根布局并清除底部内边距 View rootView = findViewById(android.R.id.content); rootView.setPadding(0, 0, 0, 0); }
如果需要在导航栏重新显示时恢复内边距,可以监听系统UI的变化(比如重写onSystemUiVisibilityChange方法),在导航栏显示时重新设置合适的padding。
方案三:调整系统UI标志
如果不需要布局延伸到系统栏区域,可以去掉LAYOUT_HIDE_NAVIGATION和LAYOUT_FULLSCREEN标志:
@Override public void onResume(){ super.onResume(); View aView = getWindow().getDecorView(); aView.setSystemUiVisibility( View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); }
这样布局会被限制在屏幕的安全区域内,BottomNavigationView会自动紧贴屏幕底部,同时导航栏显示时布局会被正常挤上去。不过这个方案只适合不需要布局覆盖系统栏的场景。
内容的提问来源于stack exchange,提问作者Tal Barda
相关产品推荐
相关产品推荐

