Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dismiss Snackbar On left swipe

Simple code below for showing the Snackbar.

public void onClick(View view) {
       Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_INDEFINITE)
               .setAction("Action", null).show();
}

This code correctly shows the Snackbar, when onClick event occurs.

Also, this snackbar can be dismissed by a swipe gesture.

But by default, only Right-swipe is dismissing the Snackbar. And I am unable to dismiss it with left-swipe.

How to dismiss snackbar on left-swipe?

like image 351
AADProgramming Avatar asked Feb 12 '16 06:02

AADProgramming


People also ask

How do I get rid of snackbar on Android?

OnClickListener() { @Override public void onClick(View v) { } }). show(); The snackbar can be dismissed by a swipe.

How do I delete snackbar?

A snackbar can be dismissed manually by calling the dismiss method on the MatSnackBarRef returned from the call to open . Only one snackbar can ever be opened at one time. If a new snackbar is opened while a previous message is still showing, the older message will be automatically dismissed.

How do I use snackbar?

Snackbar in android is a new widget introduced with the Material Design library as a replacement of a Toast. Android Snackbar is light-weight widget and they are used to show messages in the bottom of the application with swiping enabled. Snackbar android widget may contain an optional action button.

What layout is used for snack bar undo?

Creating A Snackbar With An Action Button In Android Studio: make(coordinatorLayout, "Message is deleted", snackbar. LENGTH_LONG) . setAction("UNDO", new View.


Video Answer


3 Answers

another simple and cleaner approach could be the following:

val behavior = BaseTransientBottomBar.Behavior().apply {
    setSwipeDirection(SwipeDismissBehavior.SWIPE_DIRECTION_ANY)
}
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_INDEFINITE)
    .setBehavior(behavior)
    .show()

with this you don't need to check and cast the layout params nor to use the onShown callback.

like image 114
epool Avatar answered Oct 06 '22 12:10

epool


hope this will help :

OnSwipeTouchListener.java:

import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

public class OnSwipeTouchListener implements OnTouchListener {

    private final GestureDetector gestureDetector;

    public OnSwipeTouchListener (Context ctx){
        gestureDetector = new GestureDetector(ctx, new GestureListener());
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
    }

    private final class GestureListener extends SimpleOnGestureListener {

        private static final int SWIPE_THRESHOLD = 100;
        private static final int SWIPE_VELOCITY_THRESHOLD = 100;

        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            boolean result = false;
            try {
                float diffY = e2.getY() - e1.getY();
                float diffX = e2.getX() - e1.getX();
                if (Math.abs(diffX) > Math.abs(diffY)) {
                    if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffX > 0) {
                            onSwipeRight();
                        } else {
                            onSwipeLeft();
                        }
                    }
                    result = true;
                } 
                else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffY > 0) {
                            onSwipeBottom();
                        } else {
                            onSwipeTop();
                        }
                    }
                    result = true;

            } catch (Exception exception) {
                exception.printStackTrace();
            }
            return result;
        }
    }

    public void onSwipeRight() {
    }

    public void onSwipeLeft() {
    }

    public void onSwipeTop() {
    }

    public void onSwipeBottom() {
    }
}

how to use : On MainActivity

 public class MainActivity extends AppCompatActivity {
    CoordinatorLayout coordinatorLayout;

    private Snackbar snackbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        coordinatorLayout = (CoordinatorLayout)findViewById(R.id.coordinatorLayout); 

        snackbar = Snackbar
                .make(coordinatorLayout, "Replace with your own action", Snackbar.LENGTH_INDEFINITE)
                .setAction("RETRY", null);

        snackbar.setActionTextColor(Color.RED);

        View sbView = snackbar.getView();
        TextView textView = (TextView) sbView.findViewById(android.support.design.R.id.snackbar_text);
        textView.setTextColor(Color.YELLOW);
        snackbar.show();

        textView.setOnTouchListener(new OnSwipeTouchListener(MainActivity.this)
        {
            public void onSwipeTop() {

            }
            public void onSwipeRight() {

            }
            public void onSwipeLeft() {
                snackbar.dismiss();
            }
            public void onSwipeBottom() {

            }
        });

    }
}
like image 34
Aldi Renaldi Gunawan Avatar answered Oct 06 '22 14:10

Aldi Renaldi Gunawan


In the comments someone suggested the usage of CoordinatorLayout.Behavior, this is the right approach. Handling the touch event on your own, is almost good idea, but no the right approach, because it will "break" the internal implementation of Snackbar and its Manager.

You need to replace default SwipeToDismissBehavior of the Snackbar just after you calll show() method.

     Snackbar snackbar = Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_INDEFINITE)
           .setAction("Action", null).show();
    View snackBarView = snackbar.getView();
    final ViewGroup.LayoutParams lp = snackBarView.getLayoutParams();
    if (lp instanceof CoordinatorLayout.LayoutParams) {
        final CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) lp;
        final SwipeDismissBehavior<Snackbar.SnackbarLayout> behavior = new SwipeDismissBehavior<Snackbar.SnackbarLayout>();
        behavior.setStartAlphaSwipeDistance(0.1f);
        behavior.setEndAlphaSwipeDistance(0.6f);
        behavior.setSwipeDirection(SwipeDismissBehavior.SWIPE_DIRECTION_END_TO_START);
        behavior.setListener(new SwipeDismissBehavior.OnDismissListener() {
            @Override
            public void onDismiss(View view) {
                snackbar.dismiss();
            }

            @Override
            public void onDragStateChanged(int state) {
                switch (state) {
                    case SwipeDismissBehavior.STATE_DRAGGING:
                    case SwipeDismissBehavior.STATE_SETTLING:
                        snackbar.show();
                        break;
                    case SwipeDismissBehavior.STATE_IDLE:
                        break;
                }
            }
        });
        layoutParams.setBehavior(behavior);
    }

Or shorter approach:

    View snackBarView = snackbar.getView();
    final ViewGroup.LayoutParams lp = snackBarView.getLayoutParams();
    if (lp instanceof CoordinatorLayout.LayoutParams) {
        final CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) lp;
        CoordinatorLayout.Behavior behavior = layoutParams.getBehavior();
        if(behavior instanceof SwipeDismissBehavior){
            ((SwipeDismissBehavior) behavior).setSwipeDirection(SwipeDismissBehavior.SWIPE_DIRECTION_END_TO_START); // or SwipeDismissBehavior.SWIPE_DIRECTION_ANY
        }
        layoutParams.setBehavior(behavior);
    }
like image 3
Nikola Despotoski Avatar answered Oct 06 '22 13:10

Nikola Despotoski