I got a linear layout that I want to move up when a Snackbar appears.
I saw many examples how to do this with FloatingButton, but what about a regular view?
Based on @Travis Castillo answer. Fixed problems such as:
So here is fixed code for MoveUpwardBehavior
Class :
import android.content.Context;
import android.support.annotation.Keep;
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;
@Keep
public class MoveUpwardBehavior extends CoordinatorLayout.Behavior {
public MoveUpwardBehavior() {
super();
}
public MoveUpwardBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
return dependency instanceof Snackbar.SnackbarLayout;
}
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
float translationY = Math.min(0, ViewCompat.getTranslationY(dependency) - dependency.getHeight());
//Dismiss last SnackBar immediately to prevent from conflict when showing SnackBars immediately after eachother
ViewCompat.animate(child).cancel();
//Move entire child layout up that causes objects on top disappear
ViewCompat.setTranslationY(child, translationY);
//Set top padding to child layout to reappear missing objects
//If you had set padding to child in xml, then you have to set them here by
child.setPadding(0, -Math.round(translationY), 0, 0);
return true;
}
@Override
public void onDependentViewRemoved(CoordinatorLayout parent, View child, View dependency) {
//Reset paddings and translationY to its default
child.setPadding(0, 0, 0, 0);
ViewCompat.animate(child).translationY(0).start();
}
}
This codes pushes up what user sees on screen and besides user have access to all objects in your layout while SnackBar is showing.
If you want the SnackBar cover the objects instead of pushing and besides user do have access to all objects, then you need to change method onDependentViewChanged
:
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
float translationY = Math.min(0, ViewCompat.getTranslationY(dependency) - dependency.getHeight());
//Dismiss last SnackBar immediately to prevent from conflict when showing SnackBars immediately after eachother
ViewCompat.animate(child).cancel();
//Padding from bottom instead pushing top and padding from top.
//If you had set padding to child in xml, then you have to set them here by
child.setPadding(0, 0, 0, -Math.round(translationY));
return true;
}
and method onDependentViewRemoved
:
@Override
public void onDependentViewRemoved(CoordinatorLayout parent, View child, View dependency) {
//Reset paddings and translationY to its default
child.setPadding(0, 0, 0, 0);
}
Unfortunately you will lose animation when user swipe to remove SnackBar
. And you have to use ValueAnimator
class to make animation for padding changes that makes some conflict here and you have to debug them.
https://developer.android.com/reference/android/animation/ValueAnimator.html
Any comment about animation for swipe to remove SnackBar
appreciated.
If you can skip that animation then you can use it.
Anyhow, i recommend first type.