Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FloatingActionButton does not come down when dismissing Snackbar

I am trying to use a Snackbar. I have a FloatingActionButton wrapped in a CoordinatorLayout. When the Snackbar shows, the button is correctly moved up. When it dismisses automatically, the button moves down. But if I dismiss the Snackbar programmatically, the button does not go down. My code is simple:

mSnackbar = Snackbar.make(mCoordinatorLayout, text, Snackbar.LENGTH_LONG)
                .setAction(R.string.undo, new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        undoDeleteTasks();
                    }
                });
        mSnackbar.show();

Is there a way to make the FloatingActionButton move down when the Snackbar is dismissed programmatically?

like image 491
allo86 Avatar asked Sep 26 '15 15:09

allo86


3 Answers

Try this:

Snackbar mysnack = Snackbar.make( fab, "Hi, welcome to my app!", Snackbar.LENGTH_LONG );
mysnack.getView().addOnAttachStateChangeListener( new View.OnAttachStateChangeListener() {
    @Override
    public void onViewAttachedToWindow( View v ) {

    }

    @Override
    public void onViewDetachedFromWindow( View v ) {
        fab.setTranslationY( 0 );
    }
});
mysnack.show();
like image 75
Farzad119 Avatar answered Sep 27 '22 21:09

Farzad119


The problem is, in an CoordinatorLayout, the FAB is moved because its behavior class's onDependentViewChanged() is called when the Snackbar animates in or out.

However, when you call Snabackbar.dismiss() no animation takes place. And therefore no onDependentViewChanged(). And thus movement of the FAB.

I want to know if it possible to either

  1. animate the Snackbar dismiss?
  2. create a behavior that moves the FAB when the Snackbar causes onDependentViewRemoved()?

Farzad119's answer is arguably a little brittle. My approach--although not satisfactory either--is to alter the behavior on the FAB to move the FAB down when the SnackBar is removed:

   @Override
   public void onDependentViewRemoved(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
     super.onDependentViewRemoved(parent, child, dependency);
     float translationY = Math.min(0, parent.getBottom() - child.getBottom());
     child.setTranslationY(translationY);
   }
like image 22
mmm111mmm Avatar answered Sep 27 '22 21:09

mmm111mmm


To solve this issue I defined a RelativeLayout Behavior like this. This can be done for any view, just replace all RelativeLayout with desired UI element.

public class RelativeLayoutBehavior extends CoordinatorLayout.Behavior<RelativeLayout> {

    public RelativeLayoutBehavior(Context context, AttributeSet attrs) {

    }

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, RelativeLayout child, View dependency) {
        return dependency instanceof Snackbar.SnackbarLayout;
    }

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, RelativeLayout child, final View dependency) {
        Float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight());
        child.setTranslationY(translationY);
        return true;
    }

    @Override
    public void onDependentViewRemoved(CoordinatorLayout parent, RelativeLayout child, View dependency) {
        child.setTranslationY(0);
    }
}

Then you need to add the Behavior into the RelativeLayout "android:layout_behavior" property like this. Make sure the RelativeLayout you want to slide up is inside of a CoordinateLayout also.

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_coordinate_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#323232"
    tools:context="com.choch.michaeldicioccio.myapplication.MainActivity">

    <RelativeLayout
        android:id="@+id/bottom_navigation_relative_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:gravity="bottom"
        app:layout_behavior="com.yourPackagePath.RelativeLayoutBehavior" >

        <android.support.design.widget.BottomNavigationView
            android:id="@+id/bottom_navigation"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:background="@color/colorPrimary"
            android:clickable="true"
            app:elevation="8dp"
            app:itemBackground="@color/colorPrimary"
            app:itemIconTint="@drawable/bottom_navigation_color_selector"
            app:itemTextColor="@drawable/bottom_navigation_color_selector"
            app:menu="@menu/bottom_bar_menu" />

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/add_car_fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_above="@id/bottom_navigation"
            android:layout_margin="@dimen/fab_margin"
            android:scaleType="center"
            android:src="@mipmap/ic_plus_black_36dp"
            android:tint="@color/colorPrimary"
            app:elevation="8dp"/>

    </RelativeLayout>

</android.support.design.widget.CoordinatorLayout>
like image 24
Michael DiCioccio Avatar answered Sep 27 '22 21:09

Michael DiCioccio