Mark DeSpain
Mark DeSpain

Reputation: 63

FloatingActionButton on scroll down hidden effect

I am trying to make floatingActionButton hide when scroll down and showing again when scroll up, I used setOnScrollChangeListener for ScrollView to doing that

the XML

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".DetailsActivity"
    android:orientation="vertical">

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_anchor="@id/linearLayout"
        app:layout_anchorGravity="start|bottom"
        android:layout_margin="16dp"
        android:src="@drawable/icons8_share_480"
        />

code

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
        @Override
        public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
            if (scrollY > 0 && fab.isShown()) {
                fab.setVisibility(View.GONE);
            } else if (scrollY < 0) {
                fab.setVisibility(View.VISIBLE);

            }
        }
    });
} else {
    scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
        @Override
        public void onScrollChanged() {
            int mScrollY = scrollView.getScrollY();
            if (mScrollY > 0 && fab.isShown()) {
                fab.setVisibility(View.GONE);
            } else if (mScrollY < 0) {
                fab.setVisibility(View.VISIBLE);
            }
        }
    });
}

the result.
It seems working but there are two problems sometimes when scroll the fab up does not appear, second it disappears directly without any effects the more clarify in this GIF Destination.

Upvotes: 1

Views: 3748

Answers (4)

Asim
Asim

Reputation: 7114

I achieved the same by using the following in my FAB xml. Nothing else required:

app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"

Upvotes: 2

Mark DeSpain
Mark DeSpain

Reputation: 63

Thanks to @JEFF, after monitoring the OnScrollChangeListener, I changed the value in condition to
scrollY < 22 and it's appearing again.
regarding the second issue I searching for How to doing animation and I found there are two ways to doing that

first is to using fab.hide and fab.show instead of method setVisibility();

the code after edit

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    scrollView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
        //   Log.d("ScrollView","scrollX_"+scrollX+"_scrollY_"+scrollY+"_oldScrollX_"+oldScrollX+"_oldScrollY_"+oldScrollY);
        if (scrollY > 0 && fab.isShown()) {
            fab.hide();
        } else if (scrollY < 22) {
            fab.show();

        }
    });
} else {
    scrollView.getViewTreeObserver().addOnScrollChangedListener(() -> {
        int mScrollY = scrollView.getScrollY();
        if (mScrollY > 0 && fab.isShown()) {
            fab.hide();
        } else if (mScrollY < 22) {
            fab.show();
        }
    });
}

second way is using custom scale animations for scall up, down, like this answer

Upvotes: 2

Manthan Patel
Manthan Patel

Reputation: 1852

fbListFood = findViewById(R.id.fbListFood);
scrollView = findViewById(R.id.scrollView);


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

    scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
        @Override
        public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
            if (scrollY > 0 && fbListFood.isShown()) {
                fbListFood.hide();
            } else if (scrollY < 22) {
                fbListFood.show();

            }
        }
    });
} else {
    

    scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
        @Override
        public void onScrollChanged() {
            int mScrollY = scrollView.getScrollY();
            if (mScrollY > 0 && fbListFood.isShown()) {
                fbListFood.hide();
            } else if (mScrollY < 22) {
                fbListFood.show();
            }
        }
    });
}

Upvotes: 1

JEFF
JEFF

Reputation: 267

The problem is because after you scroll to bottom from top it's true it will be hidden but it cannot know when you scroll to top because your mScrollY < 0 in the position is not truly less than 0. try using the code from this, it can give the position of old position and new then you can compare it so it will know when you starting scroll to top or bottom

This is the link: https://stackoverflow.com/a/33230992/10396176

Upvotes: 2

Related Questions