How to move a view above Snackbar just like Floati

2019-03-09 07:44发布

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?

7条回答
姐就是有狂的资本
2楼-- · 2019-03-09 08:31

Based on @Travis Castillo answer. Fixed problems such as :

Moving entire layout up and cause the objects on top of view disappear.
Doesnt push the layout up when showing SnackBars immediately after eachother.

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<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();

    }
}

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.getPaddingLeft(), ...>
    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.

查看更多
登录 后发表回答