Reputation: 904
I encountered a weird issue with Snackbars on android. I show error messages via an Snackbar + Retry-Action. When 'Retry' is clicked and the error is still here (e.g. no internet) I show the error again. This click on the action in the Snackbar automatically dismisses the currently shown one, and showing a new Snackbar while the old one still 'fades out' works as expected.
But sometimes (when I click 'Retry' ~30 times) a Snackbar doesn't show up at all after I press the button many times.
I can reproduce it with this simple code:
final View.OnClickListener retryListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
showSnackbar();
}
};
private void showSnackbar() {
Snackbar snackbar = Snackbar.make(root, "Error", BaseTransientBottomBar.LENGTH_INDEFINITE)
.setAction("Retry", retryListener)
//Callback only for debugging-purposes
.addCallback(new BaseTransientBottomBar.BaseCallback<Snackbar>() {
@Override
public void onShown(Snackbar transientBottomBar) {
super.onShown(transientBottomBar);
Log.d(TAG, "onShown called");
}
});
snackbar.show();
Log.d(TAG, "show called");
}
When I take a look at logcat after the problem occurs with this code, the last line is show called
and the onShown
-callback wasn't called anymore.
Why would this happen? Should I report this as an issue? Any workarounds known?
Upvotes: 6
Views: 2506
Reputation: 4572
Apparently, if you dismiss the current SnackBar
and wait a little to show it again, it works. I'm using a Kotlin Extension Function to make it simpler to use:
fun Snackbar.dismissAndShow() {
if (isShownOrQueued) {
dismiss()
view.postDelayed(1000L) { show() }
} else {
show()
}
}
So then I call it like:
mySnackBar.dismissAndShow()
Upvotes: 0
Reputation: 904
I haven't found a real reason why it happens nor a real solution to the problem, but I found a workaround which works for me:
private Snackbar currentlyShownSnackbar;
private void showSnackbar() {
Snackbar snackbar = Snackbar.make(...);
snackbar.show();
currentlyShownSnackbar = snackbar;
}
Simply by keeping a reference to the currently shown Snackbar, this problem doesn't happen anymore. I don't know why, maybe it is related to too early garbage-collection.
Code inspection will say that this variable is assigned but never used - this warning can be ignored.
I also added this in my Activity to prevent any possible memory leak:
public void onPause() {
super.onPause();
this.currentlyShownSnackbar = null;
}
Upvotes: 8