How can I be notified when a Snackbar has dismissed itself?

39,690

Solution 1

Google design library supports Snackbar callbacks in version 23. See Snackbar docs and Callback docs. You will then get notified when the Snackbar gets dismissed (and also when shown) and also the type of dismissal if this is useful for you:

snackbar.addCallback(new Snackbar.Callback() {

    @Override
    public void onDismissed(Snackbar snackbar, int event) {
      //see Snackbar.Callback docs for event details
      ...  
    }

    @Override
    public void onShown(Snackbar snackbar) {
       ...
    }
  });

Solution 2

snackbar.addCallback(new Snackbar.Callback() {

    @Override
    public void onDismissed(Snackbar snackbar, int event) {
        if (event == Snackbar.Callback.DISMISS_EVENT_TIMEOUT) {
            // Snackbar closed on its own
        }
    }

    @Override
    public void onShown(Snackbar snackbar) {
        ...
    }
});

Solution 3

Snackbar.addCallback in kotlin

val snackBar = Snackbar
                .make(view, "Text Snackbar", Snackbar.LENGTH_LONG)
                .addCallback(object : BaseTransientBottomBar.BaseCallback<Snackbar>() {
                    override fun onShown(transientBottomBar: Snackbar?) {
                        super.onShown(transientBottomBar)
                    }

                    override fun onDismissed(transientBottomBar: Snackbar?, event: Int) {
                        super.onDismissed(transientBottomBar, event)
                    }
                })

        val snackBarView = snackBar.view
        snackBarView.setBackgroundColor(Color.RED)
        snackBar.show()

Solution 4

Recently I stumbled upon this matter myself when for scrolling and showing Snackback, too many were shown before the first even disappeared. I had to find a way to know if the app should have laid down the Snackbar.

I personally found this solution.

It is true Snackbar itself does not offer any kind of listener for it's state/visibility, but you can still get the View Object out of Snackbar ( getView(); ). From the View Object you have the chance to use a wide variety of methods to add listeners.

To implement it you have to go out of the common "all-in-one-line" Toast/Snackbar usage, because adding listeners returns void .

I personally found OnAttachStateChangeListener to fulfill my needs.

Dropping a snipper with my code in case it might turn useful for you.

Snackbar snack = Snackbar.make(getView(), "My Placeholder Text", Snackbar.LENGTH_LONG);

snack.getView().addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
    @Override
        public void onViewAttachedToWindow(View v) {
            canDisplaySnackbar = false;
        }

    @Override
    public void onViewDetachedFromWindow(View v) {

        Handler h = new Handler();
        h.postDelayed(new Runnable() {
            @Override
            public void run() {
                canDisplaySnackbar = true;

                }
        }, 1000);
    }
});
snack.show();

Please note that this is just my implementation for my own problem, Handler with a postDelayed Runnable might not even fit your case. It was just to give a general idea of the implementation I suggested using a snippet I already own.

Solution 5

To be notified when a snackbar has been shown or dismissed, you can provide a Snackbar.Callback via setCallback(Callback).

Share:
39,690

Related videos on Youtube

Tyler Pfaff
Author by

Tyler Pfaff

Updated on August 09, 2021

Comments

  • Tyler Pfaff
    Tyler Pfaff over 2 years

    I'm using a Snackbar from the com.android.support:design:22.2.0 library. I'm using it to undo deletions. To make my life easier, I'm going to make the UI look like things are actually deleted from the data source, and if the undo button in the snack bar is not pressed, actually perform the deletions from the data source. So, I want to know when the Snackbar is no longer visible, so it's safe to delete the items.

    I can call getView() on the Snackbar, but I'm not sure what listener I should be using. I tried setOnSystemUiVisibilityChangeListener() but that didn't work, I believe it is only for the system status bar.

    Additionally, Snackbar can not be extended, as it has a private constructor.

    • Tyler Pfaff
      Tyler Pfaff over 8 years
      This feature is going to be in the next release of the support design library
  • Islam A. Hassan
    Islam A. Hassan over 8 years
    and_dev's andswer is the better answer now.
  • Amr El Aswar
    Amr El Aswar over 7 years
    nice mentioning the event, because the onDismissed is also called when the actionText is clicked
  • mjn42
    mjn42 over 7 years
    setCallBack is deprecated now, use addCallBack instead
  • jds17
    jds17 about 7 years
    setCallback() is now deprecated. Use addCallback() instead
  • WhatsThePoint
    WhatsThePoint about 6 years
    Code only answers arent encouraged as they dont provide much information for future readers please provide some explanation to what you have written
  • Janis F
    Janis F over 5 years
    Please provide a description/explanation alongside your code snippet.
  • shyamal
    shyamal over 5 years
    For most cases it's probably best to check if (event != Snackbar.Callback.DISMISS_EVENT_ACTION) instead otherwise your dismiss logic won't run if the user manually dismisses or a snackbar is dismissed by another consecutive snackbar.
  • shyamal
    shyamal over 5 years
    For most cases it's probably best to check if (event != Snackbar.Callback.DISMISS_EVENT_ACTION) instead otherwise your dismiss logic won't run if the user manually dismisses or a snackbar is dismissed by another consecutive snackbar.
  • Pratik Butani
    Pratik Butani about 5 years
    Thanks for this line event == Snackbar.Callback.DISMISS_EVENT_TIMEOUT
  • Meilianto Luffenz
    Meilianto Luffenz over 2 years
    this is amazing, been looking for kotlin version