web-dev-qa-db-fra.com

Android Support Library Snackbar avec une durée indéfinie

Je vois que la Snackbar ne prendra que LENGTH_LONG ou LENGTH_SHORT lors de la détermination de la longueur de son affichage à l'écran.

Je voudrais l'avoir affiché jusqu'à ce que quelqu'un le fasse disparaître de l'écran. C'est dans certains cas lorsque vous avez des erreurs persistantes, comme lorsque vous n'avez pas Internet et que vous souhaitez informer l'utilisateur sans le faire disparaître de l'écran après 2750 ms lors de la sélection de LENGTH_LONG.

Bien sûr, je peux utiliser setDuration à des valeurs ridiculement longues en millisecondes, mais n'y a-t-il aucun moyen de simplement le configurer pour qu'il ne disparaisse pas jusqu'à ce que l'utilisateur le rejette?

23
Simon

La dernière version de la bibliothèque de support Android Android ( 22.2.1 ), inclut désormais LENGTH_INDEFINITE .

Ce qui suit montrera le Snackbar jusqu'à ce qu'il soit fermé ou qu'un autre Snackbar soit affiché.

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

MISE À JOUR: Comme mentionné, cela est maintenant possible avec la sortie de Android support library 22.2.1, use the LENGTH_INDEFINITE flag

Il n'est pas possible de définir un affichage indéfini d'une Snackbar lorsque vous utilisez l'implémentation officielle de la bibliothèque de support de conception Android Android.

Bien que cela puisse violer la philosophie de conception matérielle d'une Snackbar, il existe des implémentations de Snackbar tierces qui le permettent. Voici un exemple:

https://github.com/nispok/snackbar

Ce projet autorise les valeurs suivantes pour la durée d'affichage:

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

Attention, ce projet n'est plus en cours de développement suite à la sortie de l'implémentation officielle de Snackbar.

10
BrentM

J'utilise com.Android.support:appcompat-v7:26.1. et Snackbar.LENGTH_INDEFINITE fonctionne comme il se doit. Un échantillon pourrait ressembler à ceci:

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