FloatingActionButton does not come down when dismissing Snackbar
Asked Answered
B

3

12

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?

Babiche answered 26/9, 2015 at 15:30 Comment(2)
Don't use coordinate layout as your view. Use the FloatingActionButton. Snackbar.make(mFab, text, Snackbar.LENGTH_LONG)Sapanwood
@EugeneH I have tried it, but there is no difference. The fab still keeps up when the snackbar is dismissed using mSnackbar.dismiss();Babiche
L
17

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();
Lessen answered 6/11, 2015 at 1:27 Comment(1)
It works! Thanks @Farzad119. Just one detail. View.OnAttachStateChangeListener was added in API Level 12. What could I use in API Level 11 or lower?Babiche
H
13

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);
   }
Huey answered 3/3, 2016 at 2:22 Comment(2)
That works for me, but i think you can just set translation Y to 0 if dependency is snackbar.snackbarLayoutCelestecelestia
Great, thanks! The explanation seems correct, although your code didn't work for me. but as @Celestecelestia mentions, settings translation Y to 0 works.Cullan
M
3

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>
Maryleemarylin answered 31/8, 2017 at 2:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.