Mohamed Mo'nes
Mohamed Mo'nes

Reputation: 450

floating action button (fab) scrolling action not working

i am trying to make the "fab" disappear when scrolling up and appear when scrolling down but nothing happens

this layout is included in other DrawerLayout

     <android.support.design.widget.CoordinatorLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:fresco="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/coord_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:layoutDirection="rtl"
tools:context="co.broccli.n5rogfeen.ProfileActivity">
<!--#android:fitsSystemWindows="true"
tools:openDrawer="start">-->
<include layout="@layout/content_scrolling" />

<View
    android:layout_width="match_parent"
    android:layout_height="30dp"

    android:background="@drawable/toolbar_dropshadow"
    app:layout_anchor="@id/appbar"
    app:layout_anchorGravity="bottom" />
<android.support.design.widget.AppBarLayout
    android:id="@+id/appbar"
    android:layout_width="match_parent"
    android:layout_height="190dp"
    android:theme="@style/AppTheme.AppBarOverlay"
    tools:layout_editor_absoluteY="-2dp"

    >

    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/toolbar_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        app:contentScrim="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|exitUntilCollapsed"
        app:toolbarId="@+id/toolbar">


        <android.support.v7.widget.LinearLayoutCompat
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|center_horizontal"
            android:orientation="vertical"
            android:paddingBottom="10dp"
            app:layout_collapseMode="parallax">

            <com.facebook.drawee.view.SimpleDraweeView
                android:id="@+id/my_image_view"
                android:layout_width="75dp"
                android:layout_height="75dp"
                android:layout_gravity="center_vertical|center_horizontal"
                fresco:placeholderImage="@color/colorAccent"
                fresco:roundAsCircle="true"
                fresco:viewAspectRatio="1.33"
                />

            <android.support.v7.widget.AppCompatTextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:text="name" />


            <android.support.v7.widget.AppCompatTextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:text="@string/acc_balance" />
        </android.support.v7.widget.LinearLayoutCompat>


        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:layout_gravity="top"
            app:layout_collapseMode="pin"
            app:popupTheme="@style/AppTheme.PopupOverlay">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:text="@string/app_name"
                android:textAppearance="@style/Base.TextAppearance.AppCompat.Large" />
        </android.support.v7.widget.Toolbar>


    </android.support.design.widget.CollapsingToolbarLayout>


</android.support.design.widget.AppBarLayout>


<android.support.design.widget.FloatingActionButton
    android:id="@+id/floating_action_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    android:layout_margin="16dp"
    android:src="@drawable/ic_mode_edit_black_24px"
    android:background="@color/colorPrimary"
    app:backgroundTint="@color/colorPrimary"
    app:fabSize="normal"

   />

the recyclerview is in the included layout "content_scrolling"

     final FloatingActionButton mFloatingActionButton = (FloatingActionButton) findViewById(R.id.floating_action_button);
    mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            if (dy > 0 && mFloatingActionButton.getVisibility() == View.VISIBLE) {
                mFloatingActionButton.hide();
            } else if (dy < 0 && mFloatingActionButton.getVisibility() != View.VISIBLE) {
                mFloatingActionButton.show();
            }
        }
    });

i although tried to use floating action button behavior but worked only when i scroll to the end and when the fab disappears it doesn't appear again

   public class ScrollAwareFABBehavior extends FloatingActionButton.Behavior { private static final String TAG = "ScrollAwareFABBehavior";

public ScrollAwareFABBehavior(Context context, AttributeSet attrs) {
    super();
}

public boolean onStartNestedScroll(CoordinatorLayout parent, FloatingActionButton child, View directTargetChild, View target, int nestedScrollAxes) {
    return true;
}

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

    return false;
}

@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout,
                           FloatingActionButton child, View target, int dxConsumed,
                           int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
    // TODO Auto-generated method stub
    super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed,
            dxUnconsumed, dyUnconsumed);

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

Upvotes: 1

Views: 1172

Answers (2)

a.yanyev
a.yanyev

Reputation: 31

As for ScrollAwareFABBehavior. FAB won't be shown again after hide() is called because due to current CoordinatorLayout.onStartNestedScroll() implementation child view's (here, FAB) behavior onStartNestedScroll method is not called anymore if it's visibility is GONE.

The solution is to set FAB's visibility to INVISIBLE right after it was hidden. Create listener inside ScrollAwareFABBehavior:

private val listener = object : FloatingActionButton.OnVisibilityChangedListener() {
    override fun onHidden(fab: FloatingActionButton?) {
        fab?.visibility = INVISIBLE
    }
}

and then:

hide(listener)

Upvotes: 0

global_warming
global_warming

Reputation: 843

If you look at the javadoc of hide() method in child.hide() of ScrollAwareFABBehavior, it's something like:

/**
 * Hides the button.
 * <p>This method will animate the button hide if the view has already been laid out.</p>
 */
public void hide() {
    hide(/* listener: */ null); // The listener to notify when this view is hidden
}

So if child.hide() is called without listener, null is passed so it won't pop-up again. You can achieve show/hide as:

if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) {
    child.setVisibility(View.INVISIBLE);
} else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) {
    child.setVisibility(View.VISIBLE);
}

Upvotes: 2

Related Questions