Clans / FloatingActionButton

Android Floating Action Button based on Material Design specification
Apache License 2.0
5.22k stars 1.13k forks source link

Hide/Show FAB #389

Open coniocharles opened 7 years ago

coniocharles commented 7 years ago

I have implemented addonscrollListener for my recyclerview since I want to hide my FAB when recyclerview is scrolled as follows 👍

mRvNearby.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                Log.e("DY",""+dy);
                if(dy<0){
                    mFloatingActionMenu.hideMenuButton(true);
                }else{
                    mFloatingActionMenu.showMenuButton(true);
                }
            }
        });

But unfortunately, when I use this listener, the "dy" only changes once, and when I scrolled continuously, the value hasn't changed. I was expecting that when scrolled down, The value will be less than 0. and when scrolled up, the value is greater than 0.

baggednismo commented 7 years ago

Here is my scroll listener for a recyclerview inside a fragment, it is working in my implementation. I have nearly the same code for multiple apps as well across the app i am copying this from where all fragments containing a RecyclerView are hiding and showing the FAB Menu as expected.

mFragment.OnScrollListener mListScrollListener = new mFragment.OnScrollListener() {
    @Override
    public void onScrolled(int dx, int dy)
    {
        if (dy > 0)
        {
            // Scroll Down
            if (!fabMenu.isMenuButtonHidden())
                fabMenu.hideMenuButton(true);
        }
        else if (dy < 0)
        {
            // Scroll Up
            if (fabMenu.isMenuButtonHidden())
                fabMenu.showMenuButton(true);
        }
    }
};
Croutonix commented 6 years ago

If you want to do this for RecyclerView, you can use this:

private static final int FAB_VISIBILITY_TOGGLE_DIFF = 100;
private int totalScrollInDir;

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

        if (-totalScrollInDir >= FAB_VISIBILITY_TOGGLE_DIFF && fabMenu.isMenuButtonHidden()) {
            fabMenu.showMenuButton(true);
        } else if (totalScrollInDir >= FAB_VISIBILITY_TOGGLE_DIFF && !fabMenu.isMenuButtonHidden()) {
            fabMenu.hideMenuButton(true);
        }
    }
});

The constant FAB_VISIBILITY_TOGGLE_DIFF is the number of pixel the user has to scroll the RecyclerView to make the FAB Menu appear or disappear. You could set a distance in dp too.