Android开发:如何让FAB不随RecyclerView滚动并置于Bottom Navigation上方
解决FAB随RecyclerView滚动的问题
这个问题其实很典型,核心原因就是你把FAB嵌套在了RecyclerView的滚动容器(比如RecyclerView的直接父布局或者RecyclerView内部)里,导致它跟着RecyclerView一起滚动。要让FAB固定在Bottom Navigation上方且不滚动,只需要调整布局结构就行,下面给你两种常用的实现方式:
方式一:使用ConstraintLayout(推荐)
ConstraintLayout是Android官方主推的布局,能灵活控制控件的位置关系,步骤如下:
- 把RecyclerView、Bottom Navigation和FAB都放在同一个
ConstraintLayout父布局下 - 给RecyclerView设置约束,让它顶部对齐父布局,底部对齐Bottom Navigation的顶部(避免RecyclerView被Bottom Nav遮挡)
- 给FAB设置约束,让它底部对齐Bottom Navigation的顶部,右侧对齐父布局右侧,再通过
layout_margin调整位置,确保它在Bottom Nav上方且不被遮挡 - 关键:绝对不要把FAB放在RecyclerView的任何子布局或者滚动容器里
示例代码如下:
<?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" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- RecyclerView --> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="0dp" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toTopOf="@id/bottomNav"/> <!-- Bottom Navigation --> <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bottomNav" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:menu="@menu/bottom_menu"/> <!-- Floating Action Button --> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="16dp" app:layout_constraintBottom_toTopOf="@id/bottomNav" app:layout_constraintEnd_toEndOf="parent" android:src="@drawable/ic_add"/> </androidx.constraintlayout.widget.ConstraintLayout>
方式二:使用RelativeLayout
如果习惯用RelativeLayout,也可以这样实现:
- 父布局用RelativeLayout,给Bottom Navigation设置
android:layout_alignParentBottom="true",让它固定在底部 - 给RecyclerView设置
android:layout_above="@id/bottomNav",确保它显示在Bottom Nav上方 - 给FAB设置
android:layout_above="@id/bottomNav"和android:layout_alignParentEnd="true",再添加margin调整位置
示例代码如下:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/bottomNav"/> <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bottomNav" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" app:menu="@menu/bottom_menu"/> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="16dp" android:layout_alignParentEnd="true" android:layout_above="@id/bottomNav" android:src="@drawable/ic_add"/> </RelativeLayout>
额外注意点
- 如果你的Fragment是动态加载到MainActivity的容器中,更推荐把FAB放在MainActivity的布局里,配合Bottom Nav一起管理;如果要放在Fragment里,那Fragment的布局要采用上述结构
- 如果需要在不同Fragment切换时显示/隐藏FAB,可以在Fragment的
onResume()和onPause()方法里调用fab.show()/fab.hide()来控制
内容的提问来源于stack exchange,提问作者user9570840
相关产品推荐
相关产品推荐

