FloatingActionButton
FloatingActionButton copied to clipboard
FloatingActionButton/Menu hide on ListView scroll
I want to hide/show FloatingActionButton/Menu on scroll of ListView. How to do this?
i found the solution for this.
use this attribute: app:layout_behavior="com.example.FABBehavior"
import android.content.Context;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.View;
import com.github.clans.fab.FloatingActionMenu;
import java.util.List;
public class FABBehavior extends CoordinatorLayout.Behavior<FloatingActionMenu> {
private int toolbarHeight;
public FABBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
this.toolbarHeight = Utils.getToolbarHeight(context);
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionMenu child, View dependency) {
return dependency instanceof AppBarLayout;
}
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionMenu fab, View dependency) {
if (dependency instanceof AppBarLayout) {
CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
int fabBottomMargin = lp.bottomMargin;
int distanceToScroll = fab.getHeight() + fabBottomMargin;
float ratio = (float) dependency.getY() / (float) toolbarHeight;
fab.setTranslationY(-distanceToScroll * ratio);
}
return true;
}
}
@Rahman-94 I am also stuck with the same issue. How to set Utils.getToolbarHeight(context) ; need this method badly.. and not works after set the had code value to this.
I had the same issue as @shihabmi7 and was able to solve it. My FloatingActionMenu is inside a FrameLayout so I decided to add the behavior to the FrameLayout.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="my.package.FloatingActionMenuInFrameLayoutBehavior">
<com.github.clans.fab.FloatingActionMenu
android:layout_width="wrap_content"
.....
</com.github.clans.fab.FloatingActionMenu>
</FrameLayout>
And the behavior code :
public class FloatingActionMenuInFrameLayoutBehavior extends CoordinatorLayout.Behavior<FrameLayout> {
public FloatingActionMenuInFrameLayoutBehavior(Context context, AttributeSet attrs) {
super();
}
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, FrameLayout child, View directTargetChild, View target, int nestedScrollAxes) {
return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL || super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
}
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, FrameLayout fabContainer, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
super.onNestedScroll(coordinatorLayout, fabContainer, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
FloatingActionMenu fabMenu = (FloatingActionMenu) fabContainer.getChildAt(0);
if (dyConsumed > 0 && !fabMenu.isMenuButtonHidden()) {
fabMenu.hideMenuButton(true);
} else if (dyConsumed < 0 && fabMenu.isMenuButtonHidden()) {
fabMenu.showMenuButton(true);
}
}
}
Adapt this to your desired behavior ;-) Hope it helps
I think this one might be an improvement on the solution provided by @eric-taix (you can apply it directly to your FloatingActionMenu
and has a threshold (equal to half of the height of the FAB).
class FloatingActionButtonScrollBehavior(context: Context, attrs: AttributeSet) : CoordinatorLayout.Behavior<FloatingActionMenu>() {
private var acumulator = 0
private var threshold = 0
override fun onStartNestedScroll(coordinatorLayout: CoordinatorLayout, child: FloatingActionMenu, directTargetChild: View, target: View, axes: Int, type: Int): Boolean {
threshold = (if (child.childCount > 0) child.getChildAt(0).height else child.height) / 2
return true
}
override fun onNestedScroll(coordinatorLayout: CoordinatorLayout, child: FloatingActionMenu, target: View, dxConsumed: Int, dyConsumed: Int, dxUnconsumed: Int, dyUnconsumed: Int, type: Int) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type)
if ((acumulator * dyConsumed) < 0) { //scroll direction change
acumulator = 0
}
acumulator += dyConsumed
if (acumulator > threshold && !child.isMenuButtonHidden) {
child.hideMenuButton(true)
} else if (acumulator < -threshold && child.isMenuButtonHidden) {
child.showMenuButton(true)
}
}
override fun onStopNestedScroll(coordinatorLayout: CoordinatorLayout, child: FloatingActionMenu, target: View, type: Int) {
super.onStopNestedScroll(coordinatorLayout, child, target, type)
acumulator = 0
}
}
then add this behavior to the FloatingActionMenu
in your XML file using app:layout_behavior
@fmrsabino Thanks for your improvement. I post it as java code here.
public class FabMenuBehavior extends CoordinatorLayout.Behavior<FloatingActionMenu> {
private int accumulator = 0;
private int threshold = 0;
public FabMenuBehavior() {
super();
}
public FabMenuBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionMenu child, View directTargetChild, View target, int nestedScrollAxes) {
threshold = (child.getChildCount() > 0 ? child.getChildAt(0).getHeight() : child.getHeight()) / 2;
return true;
}
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionMenu child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
if ((accumulator * dyConsumed) < 0) { //scroll direction change
accumulator = 0;
}
accumulator += dyConsumed;
if (accumulator > threshold && !child.isMenuButtonHidden()) {
child.hideMenuButton(true);
} else if (accumulator < -threshold && child.isMenuButtonHidden()) {
child.showMenuButton(true);
}
}
@Override
public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionMenu child, View target) {
super.onStopNestedScroll(coordinatorLayout, child, target);
accumulator = 0;
}
}