How to dismiss a Snackbar using it's own Action button?

77,573

Solution 1

For Java,

The .make method returns a Snackbar object. Save an instance of that object by making it final. Then, in the onClick(), call .dismiss:

final Snackbar snackBar = Snackbar.make(findViewById(android.R.id.content), "Snackbar Message", Snackbar.LENGTH_LONG);

        snackBar.setAction("Action Message", new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Call your action method here
                snackBar.dismiss();
            }
        });
        snackBar.show();

For Kotlin,

        Snackbar.make(
            findViewById(android.R.id.content),
            "Snackbar Message",
            Snackbar.LENGTH_INDEFINITE
        ).setAction("Action Message") {
            // Call action functions here
        }.show()

Solution 2

Implement a click action and let it empty . Clicking on empty click action will dismiss snackbar .

Snackbar.make(coordinatorLayoutView, "Service Enabled", Snackbar.LENGTH_LONG)
                        .setAction("DISMISS", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                            }
                        })
                        .show();

Solution 3

When you use Snackbar.LENGTH_LONG you do not need action button for dismiss , after second automatically dismiss. You should use this code :

 Snackbar snackbar = Snackbar.make(relativeLayout, "Your Message", Snackbar.LENGTH_INDEFINITE);
            snackbar.setAction("dismiss", new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    snackbar.dismiss();
                }
            });

            snackbar.show();

Be careful this line :

Snackbar.LENGTH_INDEFINITE

Solution 4

This is an old question, but I just want to share my own experience around similar feature on Snackbar. So we got a design for our app, that snackbar should be shown indefinitely and user should be able to dismiss it.. but there shouldn't be DISMISS button inside it (Google is not recommending Dismiss or Cancel actions inside snackbars anyway). Our snackbar had to be dismissed just by tapping on it.

The only solution, working for us, was in the end (I am using retrolambda here, but standard View.OnClickListener could be used as well):

final Snackbar snack = ... /* create proper snackbar as alway */
snack.getView().setOnClickListener(v -> snack.dismiss());

Note getView() call in the middle.

Solution 5

Snackbar (from 'com.android.support:design:23.2.1') support many types of dismiss action. You can create a simple filter by using event, such as in this example:

Snackbar.make(view, wornMessage, Snackbar.LENGTH_LONG).setActionTextColor(context.getResources().getColor(R.color.primary))
    .setCallback(new Snackbar.Callback() {
        @Override
        public void onShown(Snackbar snackbar) {
            super.onShown(snackbar);
        // when snackbar is showing
        }

        @Override
        public void onDismissed(Snackbar snackbar, int event) {
            super.onDismissed(snackbar, event);
            if (event != DISMISS_EVENT_ACTION) {
               //will be true if user not click on Action button (for example: manual dismiss, dismiss by swipe
            }
        }
    })
    .setAction("Undo, view1 -> {
        // if user click on Action button
}).show();

Snackbar's dismiss types:

/** Indicates that the Snackbar was dismissed via a swipe.*/
public static final int DISMISS_EVENT_SWIPE = 0;
/** Indicates that the Snackbar was dismissed via an action click.*/
public static final int DISMISS_EVENT_ACTION = 1;
/** Indicates that the Snackbar was dismissed via a timeout.*/
public static final int DISMISS_EVENT_TIMEOUT = 2;
/** Indicates that the Snackbar was dismissed via a call to {@link #dismiss()}.*/
public static final int DISMISS_EVENT_MANUAL = 3;
/** Indicates that the Snackbar was dismissed from a new Snackbar being shown.*/
public static final int DISMISS_EVENT_CONSECUTIVE = 4;

P.S. In sample code used lambda expressions (by RetroLambda)

Share:
77,573

Related videos on Youtube

Asim
Author by

Asim

A beginner in Android development.

Updated on July 08, 2022

Comments

  • Asim
    Asim almost 2 years

    Android design support library now includes support for Snackbar.

    I've used the following code to create one:

    Snackbar.make(findViewById(R.id.root_layout), result, Snackbar.LENGTH_LONG)
            .setAction("Dismiss", new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                }
            }).show();
    

    The snackbar can be dismissed by a swipe. However, I also want to dismiss it using its own Action Button (created using the setAction function).

    However there doesn't seem to be any function available that can do that.

  • Vinay W
    Vinay W almost 9 years
    if i do this in a coordinator layout with a FloatingActionButton, the FloatingActionButton does not come down.
  • Mark Buikema
    Mark Buikema over 8 years
    A snackbar is dismissed by default when clicking the action. Explicitly calling the dismiss method is unnecessary.
  • EE66
    EE66 over 8 years
    @MarkBuikema this feature was added later on. At the time of the question that was not the deafult behavior of the snackbar.
  • JoseF
    JoseF over 6 years
    Where do you read that "Google is not recommending Dismiss or Cancel actions inside Snackbars" ? I would like to read the reason....
  • Dariusz Wiechecki
    Dariusz Wiechecki over 6 years
    @JoseF Please check first comment under the question itself ;) It is in Material Design guidelines: material.io/guidelines/components/… ("0-1 actions, not dismiss or cancel")
  • The incredible Jan
    The incredible Jan about 6 years
    The question is not about a dismiss handler. The question is how to dismiss on button click.
  • The incredible Jan
    The incredible Jan about 6 years
    Doesn't make any sense to me. Why should you call performClick() if you actually click a button? That appears to be nonsense.
  • crgarridos
    crgarridos almost 6 years
    JFYI, the action won't be shown if the OnClickListener is null
  • Juan
    Juan about 5 years
    As of today, this code will call dismiss twice with different event value, one for clicking on the action and another one for calling dissmiss() programatically.
  • ccpizza
    ccpizza almost 4 years
    you can pass null for a listener, no need to create an actual instance
  • Androidcoder
    Androidcoder over 3 years
    This answer is unique in that it gives a way to dismiss the snackbar that's set to 'LENGTH_INDEFINITE' (so user has time to read it) without having to start whatever action the action button starts. I use a Snackbar to notify my players an update has been downloaded and to restart if they want it implemented. If they aren't ready to restart I wanted a way to dismiss it without hitting the action button. Snackbars on my test devices don't dismiss with a swipe. This code dismisses it with a touch outside the action button, which should be the default behavior in my opinion