Kroha
Kroha

Reputation: 168

How to hide Floating Action Button on Nested Scroll

I'm trying to hide two FAB on Nested Scroll scrolling. I've tried to implement my own FAB behavior but it did't work. FAB's don't react on scrolling at all. Note: I deleted some part of layout to fit the post.

Layout

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="ru.berezin.maxim.im.budget_v3.userinterface.StartPage">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appcollapse"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/testingscroll"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="none"
        app:behavior_overlapTop="30dp"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <!--content including-->
        <include layout="@layout/start_content_layout"/>

    </android.support.v4.widget.NestedScrollView>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/start_page_fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="16dp"
        android:src="@drawable/plus"
        app:layout_anchor="@id/testingscroll"
        app:layout_anchorGravity="end|bottom"
        app:layout_behavior="ru.berezin.maxim.im.budget_v3.FabOnScroll"
        />

    <View
        android:id="@+id/dummy"
        android:layout_width="1dp"
        android:layout_height="16dp"
        app:layout_anchor="@id/start_page_fab"
        app:layout_anchorGravity="top|right|end"
        />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/account_det_add_transfer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|top"
        android:layout_margin="16dp"
        android:src="@drawable/minus"
        app:layout_anchor="@id/dummy"
        app:layout_anchorGravity="top|right|end"
        app:layout_behavior="ru.berezin.maxim.im.budget_v3.FabOnScroll"
        />
</android.support.design.widget.CoordinatorLayout>

FabOnScroll class

public class FabOnScroll extends FloatingActionButton.Behavior {
        public FabOnScroll(Context context, AttributeSet attrs) {
            super();
        }

        @Override
        public void onNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
            super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);

            //child -> Floating Action Button
            if (dyConsumed > 0) {
                CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
                int fab_bottomMargin = layoutParams.bottomMargin;
                child.animate().translationY(child.getHeight() + fab_bottomMargin).setInterpolator(new LinearInterpolator()).start();
            } else if (dyConsumed < 0) {
                child.animate().translationY(0).setInterpolator(new LinearInterpolator()).start();
            }
        }

        @Override
        public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View directTargetChild, View target, int nestedScrollAxes) {
            return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL;
        }

    }

Upvotes: 1

Views: 2557

Answers (3)

Raed
Raed

Reputation: 894

I know it's a late answer but my solution is to use dyUnconsumed instead of dyConsumed inside the if statement and it worked very well with me

if (dyUnconsumed > 0 && child.getVisibility() == View.VISIBLE) {

        child.hide(new FloatingActionButton.OnVisibilityChangedListener() {
            @Override
            public void onHidden(FloatingActionButton fab) {
                super.onHidden(fab);
                child.setVisibility(View.INVISIBLE);
            }
        });

    } else if (dyUnconsumed <0 && child.getVisibility() != View.VISIBLE) {
        child.show();
    }

Upvotes: 0

Kroha
Kroha

Reputation: 168

So, I fixed it. Not exactly what I wanted, but it's working. I dont have any ideas why, but for some reason dyConsumed is always equals 0. But I noticed that dyUnconsumed is changing while I scroll. So I've just add dxUnconsumed check to my If/else statment and it's worked. Can someone explain why dyConsumed equals 0?

Upvotes: 2

Kiran Nemani
Kiran Nemani

Reputation: 67

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener()
{
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy)
{
    if (dy > 0 ||dy<0 && fab.isShown())
    {
        fab.hide();
    }
}

@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState)
{
    if (newState == RecyclerView.SCROLL_STATE_IDLE)
    {
        fab.show();
    }

    super.onScrollStateChanged(recyclerView, newState);
}
});

Upvotes: 0

Related Questions