Библиотека поддержки Android Snackbar с неопределенной длиной

Я вижу, что Snackbar будет принимать только LENGTH_LONG или LENGTH_SHORT при определении длины его отображения на экране.

Я бы хотел, чтобы он отображался, пока кто-то не вытащил его из экрана. Это касается некоторых случаев, когда у вас есть постоянные ошибки, например, когда у вас нет Интернета, и вы хотите уведомить пользователя, не покидая экран после 2750 мс при выборе LENGTH_LONG.

Конечно, я могу использовать setDuration для смехотворно длинных миллисекундных значений, но не существует способа просто настроить его так, чтобы он не исчезал, пока пользователь не отклонил его?

Ответы

Ответ 1

Последняя версия библиотеки поддержки Android (22.2.1) теперь включает LENGTH_INDEFINITE.

Далее будет показана Snackbar до тех пор, пока она не будет отклонена или не появится другая Snackbar.

Snackbar.make(view, "Your Snackbar", Snackbar.LENGTH_INDEFINITE)
        .setAction("Your Action", null).show();

Ответ 2

ОБНОВЛЕНИЕ: Как уже упоминалось, теперь это возможно при выпуске библиотеки поддержки Android 22.2.1, используйте флаг LENGTH_INDEFINITE

Невозможно установить неопределенное отображение Snackbar при использовании официальной реализации из библиотеки поддержки дизайна Android.

Если это может нарушить философию дизайна материалов в Snackbar, есть сторонние реализации Snackbar, которые позволяют это сделать. Вот пример:

https://github.com/nispok/snackbar

Этот проект позволяет использовать следующие значения для продолжительности отображения:

LENGTH_SHORT: 2s
LENGTH_LONG: 3.5s (default)
LENGTH_INDEFINTE: Indefinite; ideal for persistent errors

Помните, что этот проект больше не разрабатывается из-за выпуска официальной реализации Snackbar.

Ответ 3

Закуски автоматически выходят из экрана. Они не должны быть постоянными или быть сложены в стек, поскольку они выше других элементов на экране.

Следовательно, Snackbars кажется неподходящим для вашего случая использования уведомлений пользователей, пока пользователь не сделает что-то, чтобы его отклонить.

Вместо этого вам следует воспользоваться диалоговым окном

Диалоги всегда сохранять фокус до отклонено или выполнено требуемое действие

За дополнительной информацией обращайтесь к:

Руководство по дизайну материалов - Закуски

Руководство по дизайну материалов - Диалоги

Ответ 4

Я использую com.android.support:appcompat-v7:26.1.0 и Snackbar.LENGTH_INDEFINITE работает так, как должно быть. Образец может выглядеть следующим образом:

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();
}