Search code examples
androidandroid-coordinatorlayoutfloating-action-buttonandroid-appbarlayoutandroid-nestedscrollview

How to make the FAB react to downward scroll events before the AppBarLayout has collapsed in a CoordinatorLayout


I am trying to write a custom behaviour for the FAB. At the moment, the behaviour which I took from here controls the FAB's visibility from when the onNestedScroll() method from the CoordinatorLayout.Behavior class is called.

But, onNestedScroll() is only detecting downward scroll events (i.e. when dyConsumed > 0) (Note: dyConsumed is a param of onNestedScroll) once the AppBarLayout has reached the top of the screen (i.e. when the AppBarLayout has collapsed), and the content of the NestedScrollView (or another vertically scrollable view) is the only visible scrolling content left on screen.

I want the FAB to disappear after the user has scrolled down before the AppbBarLayout has collapsed.

I tried making the FAB dependent on another view:

 @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
       return dependency instanceof viewToDependOn;

    } 

And then make the view dissapear when this view changes state:

   @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, final FloatingActionButton child, View dependency) {

     child.setVisibility(View.GONE); 

  return true;
    }

But because onDependentViewChanged is called everytime the view that the FAB is dependent upon the method is called too frequently after touch events, so I can't make the FAB visible again once it has been made invisible.

My question in a nutshell: How do I toggle the FAB's state of visibility in a NestedScrollView without relying on the AppBarLayout's scroll events ?

If you need any more code let me know,

Thanks in advance


Solution

  • You should use:

    AppBarLayout.OnOffsetChangedListener
    

    This method: onOffsetChanged

    onNestedScroll will only detect scroll events that are not related to collapsing/expanding the AppBarLayout.

    There, you can do something like this:

    if(verticalScroll == 0)
       // appBarLayout Expanded
    else if(verticalScroll == appBarLayout.totalScrollRange())
      // appBarLayout Collapsed
    

    And hide/show your FAB based on some offset or collapse/expand mode of the appBarLayout