I see that the Snackbar will only take either LENGTH_LONG or LENGTH_SHORT when determining the length of its display on screen.
I would like to have it displayed until someone swipes it off the screen. This is for some cases when you have persistent errors, like when you have no internet and you want to notify the user without having it disappearing off the screen after 2750ms when selecting LENGTH_LONG.
Of course I can use setDuration to a ridiculously long milliseconds values, but is there no way to just set it up so that it doesn't disappears until the user dismisses it?
The latest version of the Android Support Library (22.2.1), now includes LENGTH_INDEFINITE
.
The following will show the Snackbar until it is dismissed or another Snackbar is shown.
Snackbar.make(view, "Your Snackbar", Snackbar.LENGTH_INDEFINITE)
.setAction("Your Action", null).show();
UPDATE: As mentioned this is now possible with the release of Android support library 22.2.1, use the LENGTH_INDEFINITE flag
It is not possible to set an indefinite display of a Snackbar when using the official implementation from the Android Design Support library.
While doing this may violate the Material Design philosophy of a Snackbar, there are 3rd party Snackbar implementations that do allow this. Here is an example:
https://github.com/nispok/snackbar
This project allows the following values for duration of display:
LENGTH_SHORT: 2s
LENGTH_LONG: 3.5s (default)
LENGTH_INDEFINTE: Indefinite; ideal for persistent errors
Beware that this project is no longer being developed due to the release of the official Snackbar implementation.
I am using com.android.support:appcompat-v7:26.1.0 and Snackbar.LENGTH_INDEFINITE
works just as it should be. A sample could be like the following:
private HashMap<Long, Snackbar> mTokenSnackbarMap = new LinkedHashMap<>();
private void dropPoint(@NonNull Location location) {
final Long token = SystemClock.elapsedRealtime();
// <submitPoint> is the callback to be executed
// at a time in the future, if the "cancel" button
// of the Snackbar isn't clicked until that time.
Runnable submitPoint = () -> {
Snackbar bar = mTokenSnackbarMap.get(token);
if (bar != null) {
// "cancel" button of the Snackbar wasn't clicked,
// but our time is up. Dismiss the Snackbar.
bar.dismiss();
mTokenSnackbarMap.remove(token);
Log.i(TAG, "dropPoint: dismiss snackbar");
}
mDatabase.add(Point.Factory.create(uid, location));
Log.i(TAG, "dropPoint: addPoint");
};
// The indefinite Snackbar allowing arbitrary cancellation.
Snackbar snackbar = Snackbar.make(mMainView, R.string.point_pending, Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.cancel, (v) -> {
mTokenSnackbarMap.remove(token);
mUiHandler.removeCallbacks(submitPoint, token);
Log.i(TAG, "dropPoint: cancel snackbar");
});
mTokenSnackbarMap.put(token, snackbar);
mUiHandler.postAtTime(submitPoint, token,
SystemClock.uptimeMillis() + Constants.POINT_DELAY_MILLIS);
Log.i(TAG, "dropPoint: postAtTime");
snackbar.show();
}
Snackbars automatically time out from the screen. They should not be persistent or be stacked, as they are above other elements on screen.
Hence, Snackbars seems to be unsuitable for your use case of notifying users until the user does something to dismiss it.
Instead, you should consider using Dialog
Dialogs always retain focus until dismissed or a required action has been taken
For more information, please refer to:
Material Design Guidelines - Snackbars
Material Design Guidelines - Dialogs