Search code examples
javaandroidandroid-coordinatorlayoutsnackbar

Move views up when SnackBar appears in CoordinatorLayout


I have a TextView at the bottom of the CoordinatorLayout.

But when I show a SnackBar , it will cover the TextView.

I know I have to customize a Behavior for the TextView and override layoutDependsOn and onDependentViewChanged,but it doesn't fix very well.

Could you give me some advice if you know? Thanks.


Solution

  • You need to add a behavior to your LinearLayout and embed it in a CoordinatorLayout.

    Here is how you do that.

    MoveUpwardBehavior.class

    import android.os.Build;
    import android.support.design.widget.CoordinatorLayout;
    import android.support.design.widget.Snackbar;
    import android.view.View;
    
    
    public class MoveUpwardBehavior extends CoordinatorLayout.Behavior<View> {
        private static final boolean SNACKBAR_BEHAVIOR_ENABLED;
    
        @Override
        public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
            return SNACKBAR_BEHAVIOR_ENABLED && dependency instanceof Snackbar.SnackbarLayout;
        }
    
        @Override
        public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
            float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight());
            child.setTranslationY(translationY);
            return true;
        }
    
        static {
            SNACKBAR_BEHAVIOR_ENABLED = Build.VERSION.SDK_INT >= 11;
        }
    }
    

    CustomLinearLayout.class

    import android.content.Context;
    import android.support.design.widget.CoordinatorLayout;
    import android.util.AttributeSet;
    import android.widget.LinearLayout;
    
    @CoordinatorLayout.DefaultBehavior(MoveUpwardBehavior.class)
    public class CustomLinearLayout extends LinearLayout {
        public CustomLinearLayout(Context context) {
            super(context);
        }
    
        public CustomLinearLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public CustomLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    }
    

    Sample xml->activity_home

    Here user.example.charu.its2017huree is my package name replace it with yours!

    <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:fitsSystemWindows="true"
            android:layout_height="match_parent">
            <user.example.charu.its2017huree.CustomLinearLayout
                android:background="#098"
                android:gravity="bottom"
                android:id="@+id/linearLayout"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="Hello world" />
            </user.example.charu.its2017huree.CustomLinearLayout>
    

    Finally in my Activity called HomeActivity

    public class HomeActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_home);
            CustomLinearLayout customLinearLayout = (CustomLinearLayout) findViewById(R.id.linearLayout);
            Snackbar.make(customLinearLayout, "Text to display", Snackbar.LENGTH_LONG).show();
    
        }
    
    }
    

    Source is from this example.