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:11

I'm going to elaborate on the approved answer because I think there's a slightly simpler implementation than that article provides.

I wasn't able to find a built-in behavior that handles a generic moving of views, but this one is a good general purpose option (from http://alisonhuang-blog.logdown.com/posts/290009-design-support-library-coordinator-layout-and-behavior linked in another comment):

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());
        ViewCompat.setTranslationY(child, translationY);
        return true;
    }

    //you need this when you swipe the snackbar(thanx to ubuntudroid's comment)
    @Override
    public void onDependentViewRemoved(CoordinatorLayout parent, View child, View dependency) {
        ViewCompat.animate(child).translationY(0).start();
    }
}

then, in your layout file add a layout_behavior as below:

<LinearLayout
    android:id="@+id/main_content"
    android:orientation="vertical"
    app:layout_behavior="com.example.MoveUpwardBehavior"/>

where the layout_behavior is the full path to your custom behavior. There's no need to subclass LinearLayout unless you have a specific need to have a default behavior, which seems uncommon.

查看更多
乱世女痞
3楼-- · 2019-03-09 08:11

NO need of Co-ordinator layout using a regular view align the snack bar to the bottom of the view, and place the button on top of it, on click of button of whatever your logic is show snackbar or linear layout.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
/*snackbar code

 <LinearLayout
            android:id="@+id/linear_snack bar"
            android:layout_width="match_parent"
            android:layout_height="@dimen/margin_45"
            android:layout_alignParentBottom="true"
            android:layout_marginTop="@dimen/margin_0"
            android:background="@color/dark_grey">

            <TextView
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="@color/orange"
                android:gravity="center"
                android:textColor="@color/white"
                android:textSize="@dimen/text_size_h7" />

            <TextView
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center"
                android:textSize="@dimen/text_size_h7" />
        </LinearLayout>

<View  android:layout_above="@+id/linear_snack bar"



</RelativeLayout>
查看更多
Animai°情兽
4楼-- · 2019-03-09 08:12

You need to add a behaviour to your LinearLayout and embed it in a CoordinatorLayout. You might want to read this: http://alisonhuang-blog.logdown.com/posts/290009-design-support-library-coordinator-layout-and-behavior

查看更多
Root(大扎)
5楼-- · 2019-03-09 08:14

I implemented this and found when the snackbar disappeared the view remained up with white space in the snackbars place, apparently this is known if animations have been disable on the device.

To fix this I changed the onDependentViewChanged method to store the initial Y position of the view this behaviour is attached to. Then on removal of the snackbar reset the position of that view to the stored Y position

private static float initialPositionY;

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

@Override
public void onDependentViewRemoved(CoordinatorLayout parent, View child, View dependency) {
    super.onDependentViewRemoved(parent, child, dependency);
    child.setTranslationY(initialPositionY);
}
查看更多
劫难
6楼-- · 2019-03-09 08:18

In addition to Travis Castillo's answer: To allow triggering consecutive SnackBars, within onDependentViewChanged(), you have to cancel any possibly ongoing animation started by onDependentViewRemoved():

@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
    float translationY = Math.min(0, ViewCompat.getTranslationY(dependency) - dependency.getHeight());
    ViewCompat.animate(child).cancel(); //cancel potential animation started in onDependentViewRemoved()
    ViewCompat.setTranslationY(child, translationY);
    return true;
}

Without cancelling, the LinearLayout will jump down below the 2nd SnackBar when a SnackBar is replaced by another SnackBar.

查看更多
姐就是有狂的资本
7楼-- · 2019-03-09 08:25

I've written a library which additional views can be added to animate with the SnackProgressBar. It also includes progressBar and other stuff. Try it out https://github.com/tingyik90/snackprogressbar

Suppose you have the following views to animate.

View[] views = {view1, view2, view3};

Create an instance of SnackProgressBarManager in your activity and includes the view to animate.

SnackProgressBarManager snackProgressBarManager = new SnackProgressBarManager(rootView)
        .setViewsToMove(views)

When a SnackProgressBar is shown or dismissed, these views will be animated accordingly.

查看更多
登录 后发表回答