If you are using Android Studio -> File -> New -> Activity -> Scrolling Activity
with FloatingActionButton
anchored to AppBarLayout
with CollapsingToolbarLayout
, FloatingActionButton
is capable of automatic show and hide on scroll.
Sadly, by anchoring FloatingActionButton
to NestedScrollView
or RecyclerView
(or shown without anchor), automatic show and hide FloatingActionButton
on scroll doesn't work.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.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:id="@+id/rootView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="false"
tools:context="com.mydomain.myapp.MainActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="@dimen/app_bar_height"
android:fitsSystemWindows="true"
android:theme="@style/AppTheme.AppBarOverlay"
app:expanded="true">
<!-- app:layout_scrollFlags="scroll|exitUntilCollapsed" -->
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/toolbarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:toolbarId="@+id/toolbar">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
>
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/fab_margin"
app:layout_anchor="@id/appBar"
app:layout_anchorGravity="bottom|end"
android:tint="@color/fab_tint"
app:srcCompat="@drawable/ic_edit_black_24dp" />
</android.support.design.widget.CoordinatorLayout>
To enable FloatingActionButton
to automatic show and hide on scroll, we need to create ScrollAwareFABBehavior
by extending FloatingActionButton.Behavior.The following code is based on CodePath's code and code suggestion by jairobjunior.
class ScrollAwareFABBehavior(context: Context, attrs: AttributeSet): FloatingActionButton.Behavior(context, attrs) { 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) { super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type) if (dyConsumed > 0 && child.visibility == View.VISIBLE) { child.hide(object : FloatingActionButton.OnVisibilityChangedListener() { override fun onHidden(fab: FloatingActionButton) { super.onHidden(fab) fab.visibility = View.INVISIBLE } }) // } else if (dyUnconsumed < 0 && child.visibility != View.VISIBLE) { } else if (dyConsumed < 0 && child.visibility != View.VISIBLE) { child.show() } }}
Set FloatingActionButton app:layout_behavior
to ScrollAwareFABBehavior
for fab to auto hide and show on scroll.
<android.support.design.widget.CoordinatorLayout ...>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
app:layout_behavior="com.mydomain.myapp.ScrollAwareFABBehavior"
android:layout_margin="@dimen/fab_margin"
android:tint="@color/fab_tint"
app:srcCompat="@drawable/ic_add_black_24dp" />
</android.support.design.widget.CoordinatorLayout>