基于@Travis Castillo 的回答。修复了以下问题:
- 向上移动整个布局并导致视图顶部的对象消失。
- 当 SnackBars 紧随其后显示时,不会向上推布局。
所以这里是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<View> {
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.getPaddingLeft(), ...>
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();
}
}
此代码会提升用户在屏幕上看到的内容,而且用户可以在 SnackBar 显示时访问您布局中的所有对象。
如果您希望 SnackBar 覆盖对象而不是推送,并且用户确实可以访问所有对象,那么您需要更改方法 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.getPaddingLeft(), ...>
child.setPadding(0, 0, 0, -Math.round(translationY));
return true;
}
和方法onDependentViewRemoved:
@Override
public void onDependentViewRemoved(CoordinatorLayout parent, View child, View dependency) {
//Reset paddings and translationY to its default
child.setPadding(0, 0, 0, 0);
}
不幸的是,当用户滑动删除SnackBar 时,您将失去动画。而且您必须使用ValueAnimator 类为填充更改制作动画,这会在此处产生一些冲突,并且您必须对其进行调试。
https://developer.android.com/reference/android/animation/ValueAnimator.html
任何关于滑动删除SnackBar动画的评论表示赞赏。
如果您可以跳过该动画,那么您可以使用它。
无论如何,我推荐第一种。