I have a RecyclerView inside a CoordinatorLayout along with a FAB :
<androidx.coordinatorlayout.widget.CoordinatorLayout
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">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:id="@+id/empty"
android:visibility="invisible"
android:textSize="@dimen/title"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/margin"
android:src="@drawable/add"
android:layout_gravity="bottom|right"
app:fabSize="normal"
app:tint="@android:color/white" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
When attaching behaviour to FAB like this :
(fab.layoutParams as CoordinatorLayout.LayoutParams).behavior = ScrollAwareFABBehavior()
Then first click event is not dispatched to item views click listeners (ViewHolder.itemView.setOnClickListener()
) when FAB is hidden. Here is behaviour implementation :
class ScrollAwareFABBehavior : FloatingActionButton.Behavior() {
override fun onStartNestedScroll(coordinatorLayout: CoordinatorLayout, child: FloatingActionButton, directTargetChild: View, target: View, axes: Int, type: Int): Boolean {
return axes == ViewCompat.SCROLL_AXIS_VERTICAL || super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, axes, type)
}
override fun onNestedScroll(coordinatorLayout: CoordinatorLayout, child: FloatingActionButton, target: View, dxConsumed: Int, dyConsumed: Int, dxUnconsumed: Int, dyUnconsumed: Int, type: Int, consumed: IntArray) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type, consumed)
if (dyConsumed > 0) {
child.hide(object : OnVisibilityChangedListener() {
override fun onHidden(fab: FloatingActionButton) {
super.onHidden(fab)
fab.visibility = View.INVISIBLE
}
})
} else if (dyConsumed < 0) {
child.show()
}
}
}
OnStartNestedScroll gets called but not the item click listener unless I really take care not to scroll screen from 1px when clicking recycler item.
Everything works as expected when :
- removing behaviour from FAB
- removing OnVisibilityChangedListener from behaviour implementation
- or removing only
fab.visibility = View.INVISIBLE
from behaviour impl
But without the fab.visibility = View.INVISIBLE
FAB never shows up again after it has been hidden by the FabBehaviour (F.A.B Hides but Doesn't Show)...
If anyone can help me show/hide the FAB using behaviour and not have first click not delivered to item view, it would be great !