Android中如何将Fragment置于Bottom Navigation Bar下方?
问题
现有activity_home.xml和fragment_task.xml布局文件,当前Fragment中的TextView显示在Bottom Navigation Bar上方(与导航栏重叠),需要实现Fragment所有内容位于Bottom Navigation Bar之后(即导航栏显示在Fragment内容的上层,内容不会覆盖导航栏区域)。
原activity_home.xml代码:
<?xml version="1.0" encoding="utf-8"?> <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".ui.ui_elements.HomeActivity"> <com.google.android.material.bottomappbar.BottomAppBar android:id="@+id/bottomAppbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" app:fabCradleMargin="13dp" android:paddingVertical="9dp" app:fabCradleVerticalOffset="4dp" app:fabCradleRoundedCornerRadius="20dp" app:addElevationShadow="true" > <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bottomNavigationView" android:layout_width="match_parent" android:layout_height="match_parent" app:menu="@menu/bottom_nav_menu" android:background="@drawable/transparent_background" app:itemIconSize="30dp" android:layout_marginHorizontal="16dp" app:labelVisibilityMode="unlabeled" app:itemHorizontalTranslationEnabled="false" /> </com.google.android.material.bottomappbar.BottomAppBar> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/addTaskFab" android:layout_width="wrap_content" android:layout_height="wrap_content" app:fabCustomSize="80dp" app:maxImageSize="60dp" android:src="@drawable/baseline_add_60" app:layout_anchor="@id/bottomAppbar" android:contentDescription="TODO" tools:ignore="ContentDescription,HardcodedText" /> <FrameLayout android:id="@+id/fragmentFrameLoader" android:layout_width="match_parent" android:layout_height="match_parent"> </FrameLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
原fragment_task.xml代码:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".ui.ui_elements.TaskFragment"> <!-- TODO: Update blank fragment layout --> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="@font/lexend" android:text="Task Fragment" android:textSize="30dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.497" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.952" /> </androidx.constraintlayout.widget.ConstraintLayout>
解决方案
方法1:调整视图层级顺序
在CoordinatorLayout中,视图的声明顺序决定了显示层级——后声明的视图会覆盖在先声明的视图之上。当前FrameLayout(Fragment容器)在底部导航栏之后声明,导致Fragment内容显示在导航栏上方。
只需将FrameLayout移到BottomAppBar之前,让导航栏层级更高,即可让Fragment内容位于导航栏之后:
修改后的activity_home.xml:
<?xml version="1.0" encoding="utf-8"?> <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".ui.ui_elements.HomeActivity"> <!-- 将Fragment容器移至底部导航栏之前,降低其层级 --> <FrameLayout android:id="@+id/fragmentFrameLoader" android:layout_width="match_parent" android:layout_height="match_parent"> </FrameLayout> <com.google.android.material.bottomappbar.BottomAppBar android:id="@+id/bottomAppbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" app:fabCradleMargin="13dp" android:paddingVertical="9dp" app:fabCradleVerticalOffset="4dp" app:fabCradleRoundedCornerRadius="20dp" app:addElevationShadow="true"> <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bottomNavigationView" android:layout_width="match_parent" android:layout_height="match_parent" app:menu="@menu/bottom_nav_menu" android:background="@drawable/transparent_background" app:itemIconSize="30dp" android:layout_marginHorizontal="16dp" app:labelVisibilityMode="unlabeled" app:itemHorizontalTranslationEnabled="false"/> </com.google.android.material.bottomappbar.BottomAppBar> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/addTaskFab" android:layout_width="wrap_content" android:layout_height="wrap_content" app:fabCustomSize="80dp" app:maxImageSize="60dp" android:src="@drawable/baseline_add_60" app:layout_anchor="@id/bottomAppbar" android:contentDescription="TODO" tools:ignore="ContentDescription,HardcodedText" /> </androidx.coordinatorlayout.widget.CoordinatorLayout>
方法2:限制Fragment容器的显示范围
如果不想调整层级顺序,可以通过给FrameLayout设置底部内边距或使用CoordinatorLayout的内置属性,让Fragment内容不延伸到导航栏区域:
方式A:使用系统属性设置底部内边距
<FrameLayout android:id="@+id/fragmentFrameLoader" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="?attr/actionBarSize"> </FrameLayout>
?attr/actionBarSize会自动适配系统导航栏的高度,避免硬编码数值。
方式B:使用CoordinatorLayout的避让属性
<FrameLayout android:id="@+id/fragmentFrameLoader" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_dodgeInsetEdges="bottom"> </FrameLayout>
该属性会让CoordinatorLayout自动处理底部边距,确保Fragment内容不被底部导航栏遮挡。
内容的提问来源于stack exchange,提问作者Arya_
相关产品推荐
相关产品推荐

