Un Toast Android peut-il être plus long que Toast.LENGTH_LONG?


263

Lors de l'utilisation de setDuration () pour un Toast, est-il possible de définir une longueur personnalisée ou au moins quelque chose de plus long que Toast.LENGTH_LONG?


4
@Nicolae, pourquoi avez-vous supprimé le toasttag? Cela semble pertinent pour la question ..
Shadow Wizard est Ear For You

2
@ShadowWizard Les balises, me semble-t-il, devraient refléter les sujets de la question qui présente un grand intérêt. Comme par exemple, il est marqué Android et donc un gourou Android trouvera cette question. Toast n'aide pas du tout cette question et ressemble plus à une balise inutile. Si le pain grillé est bon, car la question concerne le tag dans Android, la longueur était également un bon tag. Hack, chaque mot dans la question devrait être une balise ... Pas de manque de respect, juste pour faire valoir mon point de vue :)
Nicu Surdu

11
J'utilise la toastbalise pour. Je pensais que les balises étaient là pour aider à la recherche et au tri et toastc'est certainement une recherche courante. androidet toastsemblent parfaits.
ChrisWilson4

Réponses:


142

Les valeurs de LENGTH_SHORTet LENGTH_LONGsont 0 et 1. Cela signifie qu'elles sont traitées comme des indicateurs plutôt que des durées réelles, donc je ne pense pas qu'il sera possible de définir la durée sur autre chose que ces valeurs.

Si vous souhaitez afficher un message à l'utilisateur plus longtemps, envisagez une notification de barre d'état . Les notifications de la barre d'état peuvent être annulées par programme lorsqu'elles ne sont plus pertinentes.


1
Merci pour la suggestion sur la barre d'état, mais je vais avec une activité de dialogue personnalisée.

337

Si vous creusez plus profondément dans le code Android, vous pouvez trouver les lignes qui indiquent clairement que nous ne pouvons pas modifier la durée du message Toast.

 NotificationManagerService.scheduleTimeoutLocked() {
    ...
    long delay = immediate ? 0 : (r.duration == Toast.LENGTH_LONG ? LONG_DELAY : SHORT_DELAY);
    }

et les valeurs par défaut pour la durée sont

private static final int LONG_DELAY = 3500; // 3.5 seconds
private static final int SHORT_DELAY = 2000; // 2 seconds

4
Merci ... c'était exactement ce dont j'avais besoin.
mcherm

3
Merci d'avoir publié les valeurs par défaut! J'avais peur de ne pas pouvoir les trouver.
Amplify91

1
Je cherchais également les valeurs de toast par défaut, c'était le premier coup. Certainement un vote positif. Merci!
Dave

120

Vous voudrez peut-être essayer:

for (int i=0; i < 2; i++)
{
      Toast.makeText(this, "blah", Toast.LENGTH_LONG).show();
}

pour doubler le temps. Si vous spécifiez 3 au lieu de 2, cela triplera le temps..etc.


17
message clignote :(
Deniz

61
Cette solution est mauvaise car, par exemple, si vous quittez l'activité avant l'heure du toast, elle clignotera encore et encore ...
dwbrito

@dwbrito: totalement d'accord et donc -1
Fahim Parkar

[+1] pour la réponse .... L'annulation du toast peut être gérée en utilisant Toast.cancel()aux endroits appropriés
Devrath

1
Oui, il peut être implémenté, mais le toast clignotera autant que vous spécifiez le nombre
HendraWD

31

Si vous voulez qu'un Toastpersiste, j'ai trouvé que vous pouvez le contourner en ayant un Timerappel à toast.show()plusieurs reprises (chaque seconde devrait le faire). L'appel show()ne casse rien si le Toastest déjà affiché, mais il actualise le temps qu'il reste à l'écran.


3
Le problème avec cela est que si l'utilisateur touche l'écran, le toast sera caché par Android mais recréé par minuterie.
Violet Giraffe

2
@VioletGiraffe qui est assez trivial à gérer avec quelque chose comme un drapeau booléen dans votre ViewGroup OnTouchévénement. Pour optimiser cela, vous devriez probablement faire répéter votre minuterie au plus près de l'heure réelle Toastaffichée à l'écran (3,5 secondes pour longtemps, 2 secondes pour court)
syklon

18

J'ai développé une classe de pain grillé personnalisé avec laquelle vous pouvez montrer du pain grillé pour une durée souhaitée (en Milli secondes)

import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;

public final class ToastHelper {

    private static final String TAG = ToastHelper.class.getName();

    public static interface OnShowListener {
        public void onShow(ToastHelper toast);
    }

    public static interface OnDismissListener {
        public void onDismiss(ToastHelper toast);
    }

    private static final int WIDTH_PADDING_IN_DIP = 25;
    private static final int HEIGHT_PADDING_IN_DIP = 15;
    private static final long DEFAULT_DURATION_MILLIS = 2000L;

    private final Context context;
    private final WindowManager windowManager;
    private View toastView;

    private int gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
    private int mX;
    private int mY;
    private long duration = DEFAULT_DURATION_MILLIS;
    private CharSequence text = "";
    private int horizontalMargin;
    private int verticalMargin;
    private WindowManager.LayoutParams params;
    private Handler handler;
    private boolean isShowing;
    private boolean leadingInfinite;

    private OnShowListener onShowListener;
    private OnDismissListener onDismissListener;

    private final Runnable timer = new Runnable() {

        @Override
        public void run() {
            cancel();
        }
    };

    public ToastHelper(Context context) {
        Context mContext = context.getApplicationContext();
        if (mContext == null) {
            mContext = context;
        }
        this.context = mContext;
        windowManager = (WindowManager) mContext
                .getSystemService(Context.WINDOW_SERVICE);
        init();
    }

    private void init() {
        mY = context.getResources().getDisplayMetrics().widthPixels / 5;
        params = new WindowManager.LayoutParams();
        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
        params.width = WindowManager.LayoutParams.WRAP_CONTENT;
        params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
        params.format = android.graphics.PixelFormat.TRANSLUCENT;
        params.type = WindowManager.LayoutParams.TYPE_TOAST;
        params.setTitle("ToastHelper");
        params.alpha = 1.0f;
        // params.buttonBrightness = 1.0f;
        params.packageName = context.getPackageName();
        params.windowAnimations = android.R.style.Animation_Toast;
    }

    @SuppressWarnings("deprecation")
    @android.annotation.TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private View getDefaultToastView() {
        TextView textView = new TextView(context);
        textView.setText(text);
        textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.START);
        textView.setClickable(false);
        textView.setFocusable(false);
        textView.setFocusableInTouchMode(false);
        textView.setTextColor(android.graphics.Color.WHITE);
        // textView.setBackgroundColor(Color.BLACK);
        android.graphics.drawable.Drawable drawable = context.getResources()
                .getDrawable(android.R.drawable.toast_frame);
        if (Build.VERSION.SDK_INT < 16) {
            textView.setBackgroundDrawable(drawable);
        } else {
            textView.setBackground(drawable);
        }
        int wP = getPixFromDip(context, WIDTH_PADDING_IN_DIP);
        int hP = getPixFromDip(context, HEIGHT_PADDING_IN_DIP);
        textView.setPadding(wP, hP, wP, hP);
        return textView;
    }

    private static int getPixFromDip(Context context, int dip) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                dip, context.getResources().getDisplayMetrics());
    }

    public void cancel() {
        removeView(true);
    }

    private void removeView(boolean invokeListener) {
        if (toastView != null && toastView.getParent() != null) {
            try {
                Log.i(TAG, "Cancelling Toast...");
                windowManager.removeView(toastView);
                handler.removeCallbacks(timer);
            } finally {
                isShowing = false;
                if (onDismissListener != null && invokeListener) {
                    onDismissListener.onDismiss(this);
                }
            }
        }
    }

    public void show() {
        if (leadingInfinite) {
            throw new InfiniteLoopException(
                    "Calling show() in OnShowListener leads to infinite loop.");
        }
        cancel();
        if (onShowListener != null) {
            leadingInfinite = true;
            onShowListener.onShow(this);
            leadingInfinite = false;
        }
        if (toastView == null) {
            toastView = getDefaultToastView();
        }
        params.gravity = android.support.v4.view.GravityCompat
                .getAbsoluteGravity(gravity, android.support.v4.view.ViewCompat
                        .getLayoutDirection(toastView));
        if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) {
            params.horizontalWeight = 1.0f;
        }
        if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.FILL_VERTICAL) {
            params.verticalWeight = 1.0f;
        }
        params.x = mX;
        params.y = mY;
        params.verticalMargin = verticalMargin;
        params.horizontalMargin = horizontalMargin;

        removeView(false);
        windowManager.addView(toastView, params);
        isShowing = true;
        if (handler == null) {
            handler = new Handler();
        }
        handler.postDelayed(timer, duration);
    }

    public boolean isShowing() {
        return isShowing;
    }

    public void setDuration(long durationMillis) {
        this.duration = durationMillis;
    }

    public void setView(View view) {
        removeView(false);
        toastView = view;
    }

    public void setText(CharSequence text) {
        this.text = text;
    }

    public void setText(int resId) {
        text = context.getString(resId);
    }

    public void setGravity(int gravity, int xOffset, int yOffset) {
        this.gravity = gravity;
        mX = xOffset;
        mY = yOffset;
    }

    public void setMargin(int horizontalMargin, int verticalMargin) {
        this.horizontalMargin = horizontalMargin;
        this.verticalMargin = verticalMargin;
    }

    public long getDuration() {
        return duration;
    }

    public int getGravity() {
        return gravity;
    }

    public int getHorizontalMargin() {
        return horizontalMargin;
    }

    public int getVerticalMargin() {
        return verticalMargin;
    }

    public int getXOffset() {
        return mX;
    }

    public int getYOffset() {
        return mY;
    }

    public View getView() {
        return toastView;
    }

    public void setOnShowListener(OnShowListener onShowListener) {
        this.onShowListener = onShowListener;
    }

    public void setOnDismissListener(OnDismissListener onDismissListener) {
        this.onDismissListener = onDismissListener;
    }

    public static ToastHelper makeText(Context context, CharSequence text,
            long durationMillis) {
        ToastHelper helper = new ToastHelper(context);
        helper.setText(text);
        helper.setDuration(durationMillis);
        return helper;
    }

    public static ToastHelper makeText(Context context, int resId,
            long durationMillis) {
        String string = context.getString(resId);
        return makeText(context, string, durationMillis);
    }

    public static ToastHelper makeText(Context context, CharSequence text) {
        return makeText(context, text, DEFAULT_DURATION_MILLIS);
    }

    public static ToastHelper makeText(Context context, int resId) {
        return makeText(context, resId, DEFAULT_DURATION_MILLIS);
    }

    public static void showToast(Context context, CharSequence text) {
        makeText(context, text, DEFAULT_DURATION_MILLIS).show();
    }

    public static void showToast(Context context, int resId) {
        makeText(context, resId, DEFAULT_DURATION_MILLIS).show();
    }

    private static class InfiniteLoopException extends RuntimeException {
        private static final long serialVersionUID = 6176352792639864360L;

        private InfiniteLoopException(String msg) {
            super(msg);
        }
    }
}

android.view.WindowManager $ BadTokenException: impossible d'ajouter une fenêtre - le jeton null n'est pas valide; est votre activité en cours?
Ahamadullah Saikat

13

J'ai codé une classe d'aide pour ce faire. Vous pouvez voir le code sur github: https://github.com/quiqueqs/Toast-Expander/blob/master/src/com/thirtymatches/toasted/ToastedActivity.java

Voici comment afficher un toast pendant 5 secondes (ou 5000 millisecondes):

Toast aToast = Toast.makeText(this, "Hello World", Toast.LENGTH_SHORT);
ToastExpander.showFor(aToast, 5000);

Thx et Nice mais comment arrêter le fil onDestroy par exemple? J'ai essayé de le faire, mais je n'en suis pas sûr: public static void cancel (Toast mytoast) {if (null! = T) t.stop (); mytoast.cancel (); }
hornetbzz

10

Je sais que je suis un peu en retard, mais j'ai pris la réponse de Regis_AG et l'ai emballée dans une classe d'aide et cela fonctionne très bien.

public class Toaster {
  private static final int SHORT_TOAST_DURATION = 2000;

  private Toaster() {}

  public static void makeLongToast(String text, long durationInMillis) {
    final Toast t = Toast.makeText(App.context(), text, Toast.LENGTH_SHORT);
    t.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 0);

    new CountDownTimer(Math.max(durationInMillis - SHORT_TOAST_DURATION, 1000), 1000) {
      @Override
      public void onFinish() {
        t.show();
      }

      @Override
      public void onTick(long millisUntilFinished) {
        t.show();
      }
    }.start();
  }
}

Dans votre code d'application, faites simplement quelque chose comme ceci:

    Toaster.makeLongToast("Toasty!", 8000);

Cela fonctionne réellement! mais comment pouvez-vous le rendre personnalisable et tactile?
développeur Android

Désolé pour cette question de débutant, mais lorsque je crée la classe Toaster ci-dessus, elle dit qu'elle ne peut pas résoudre le symbole «App» dans la ligne. Toast final t = Toast.makeText (App.context (), texte, Toast.LENGTH_SHORT); Merci et excuses.
Brian Fleming du

Oh désolé a propos de ca! App.context () est fondamentalement un morceau de code personnalisé que j'avais écrit pour accéder à ApplicationContext de manière pratique depuis n'importe où sans le faire circuler. Pas un modèle que vous utiliseriez pour beaucoup de choses, mais j'ai trouvé que cela avait du sens pour ApplicationContext. Vous souhaiterez peut-être modifier cet extrait pour passer ApplicationContext dans la méthode en tant qu'argument.
Chris Aitchison

9

Je sais que la réponse est assez tardive. J'ai eu le même problème et j'ai décidé d'implémenter ma propre version de Toast Bones, après avoir examiné le code source d'Android pour toast.

Fondamentalement, vous devez créer un nouveau gestionnaire de fenêtres et afficher et masquer la fenêtre pour la durée souhaitée à l'aide d'un gestionnaire

 //Create your handler
 Handler mHandler = new Handler();

//Custom Toast Layout
mLayout = layoutInflater.inflate(R.layout.customtoast, null);

//Initialisation 

mWindowManager = (WindowManager) context.getApplicationContext()
            .getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams();

params.gravity = Gravity.BOTTOM
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
params.format = PixelFormat.TRANSLUCENT;
params.windowAnimations = android.R.style.Animation_Toast;
params.type = WindowManager.LayoutParams.TYPE_TOAST;

Après l'initialisation de la mise en page, vous pouvez utiliser vos propres méthodes de masquage et d'affichage

    public void handleShow() {
    mWindowManager.addView(mLayout, mParams);
    }

    public void handleHide() {
        if (mLayout != null) {
            if (mLayout.getParent() != null) {
                mWindowManager.removeView(mLayout);
            }
                         mLayout = null;
        }

Maintenant, tout ce dont vous avez besoin est d'ajouter deux threads exécutables qui appellent le handleShow () et le handleHide () que vous pourriez publier dans le gestionnaire.

    Runnable toastShowRunnable = new Runnable() {
        public void run() {
            handleShow();
        }
    };

 Runnable toastHideRunnable = new Runnable() {
        public void run() {
            handleHide();
        }
    }; 

et la dernière partie

public void show() {

    mHandler.post(toastShowRunnable);
    //The duration that you want
    mHandler.postDelayed(toastHideRunnable, mDuration);

}

Ce fut une mise en œuvre rapide et sale .. N'ont pris aucune performance en considération.


1
J'ai essayé de l'exécuter (y compris l'appel à "show ()") mais rien n'apparaît (testé sur Android 7.1). Je pense que vous manquez quelque chose. De plus, où se trouve la partie ici qui empêche la suppression de la vue, car un toast disparaît après un court instant?
développeur Android

8

Affichage du toast LONG_DELAY pendant 3,5 sec et affichage du toast SHORT_DELAY pendant 2 sec .

Toast utilise en interne INotificationManager et appelle sa méthode enqueueToast chaque fois qu'un Toast.show () est appelé.

Appeler le show () avec SHORT_DELAY deux fois mettra à nouveau le même toast en file d'attente. il s'affichera pendant 4 secondes (2 secondes + 2 secondes).

de même, appeler show () avec LONG_DELAY deux fois mettra à nouveau le même toast en file d'attente. il s'affichera pendant 7 sec (3,5 sec + 3,5 sec)


6

Voici une classe Toast personnalisée que j'ai créée en utilisant le code ci-dessus:

import android.content.Context;
import android.os.CountDownTimer;
import android.widget.Toast;

public class CustomToast extends Toast {
    int mDuration;
    boolean mShowing = false;
    public CustomToast(Context context) {
        super(context);
        mDuration = 2;
    }


    /**
     * Set the time to show the toast for (in seconds) 
     * @param seconds Seconds to display the toast
     */
    @Override
    public void setDuration(int seconds) {
        super.setDuration(LENGTH_SHORT);
        if(seconds < 2) seconds = 2; //Minimum
        mDuration = seconds;
    }

    /**
     * Show the toast for the given time 
     */
    @Override
    public void show() {
        super.show();

        if(mShowing) return;

        mShowing = true;
        final Toast thisToast = this;
        new CountDownTimer((mDuration-2)*1000, 1000)
        {
            public void onTick(long millisUntilFinished) {thisToast.show();}
            public void onFinish() {thisToast.show(); mShowing = false;}

        }.start();  
    }
}

5

Si vous avez besoin d'un long Toast, il existe une alternative pratique, mais cela nécessite que votre utilisateur clique sur un bouton OK pour le faire disparaître. Vous pouvez utiliser un AlertDialog comme celui-ci:

String message = "This is your message";
new AlertDialog.Builder(YourActivityName.this)
    .setTitle("Optional Title (you can omit this)")
    .setMessage(message)
    .setPositiveButton("ok", null)
    .show();

Si vous avez un long message, il y a de fortes chances que vous ne sachiez pas combien de temps il faudra à votre utilisateur pour lire le message, donc parfois c'est une bonne idée d'exiger de votre utilisateur qu'il clique sur un bouton OK pour continuer. Dans mon cas, j'utilise cette technique lorsqu'un utilisateur clique sur une icône d'aide.


1
C'est intelligent, mais ne peut pas être implémenté dans quelque chose comme un Service, où il n'y a pas d'interface utilisateur.
mike47

@mikejeep En fait, j'ai récemment vu un exemple de Google, montrant une boîte de dialogue sans activité: developer.android.com/samples/AppShortcuts/index.html
développeur Android

5

Comme mentionné par d'autres utilisateurs, Android Toasts peut être LENGTH_LONG ou LENGTH_SHORT. Il n'y a aucun moyen de contourner cela, et vous ne devez pas non plus suivre les «hacks» publiés.

Le but de Toasts est d'afficher des informations "non essentielles" et en raison de leur effet persistant, les messages peuvent être mis hors contexte si leur durée dépasse un certain seuil. Si les toasts en stock ont ​​été modifiés de manière à pouvoir s'afficher plus longtemps que LENGTH_LONG, le message persiste à l'écran jusqu'à la fin du processus de l'application, car des vues de toasts sont ajoutées au WindowManager et non à un ViewGroup dans votre application. Je suppose que c'est pourquoi il est codé en dur.

Si vous devez absolument afficher un message de style toast de plus de trois secondes et demie, je recommande de créer une vue attachée au contenu de l'activité, de cette façon, elle disparaîtra lorsque l'utilisateur quittera l'application. Ma bibliothèque SuperToasts traite de ce problème et bien d'autres, n'hésitez pas à l'utiliser! Vous seriez très probablement intéressé à utiliser SuperActivityToasts


4

Utilisez simplement SuperToast pour faire un toast élégant dans n'importe quelle situation. Rendez votre toast coloré . Modifiez la couleur de votre police et sa taille . J'espère que ce sera tout en un pour vous.



3

Voici une méthode très simple qui a fonctionné pour moi:

for (int i=0; i < 3; i++) { Toast.makeText(this, "MESSAGE", Toast.LENGTH_SHORT).show(); }

La durée de LENGTH_SHORT est de 2 secondes et LENGTH_LONG de 3,5 secondes. Ici, le message toast sera affiché pendant 6 secondes car il est enfermé dans une boucle for. Mais un inconvénient de cette méthode est qu'après chaque 2 secondes, un petit effet de décoloration peut se produire. mais ce n'est pas très visible. J'espère que c'est utile


2

L'utilisateur ne peut pas personnaliser la durée du Toast. car la fonction scheduleTimeoutLocked () de NotificationManagerService n'utilise pas la durée du champ. le code source est le suivant.

private void scheduleTimeoutLocked(ToastRecord r, boolean immediate)
    {
        Message m = Message.obtain(mHandler, MESSAGE_TIMEOUT, r);
        long delay = immediate ? 0 : (r.duration == Toast.LENGTH_LONG ? LONG_DELAY : SHORT_DELAY);
        mHandler.removeCallbacksAndMessages(r);
        mHandler.sendMessageDelayed(m, delay);
    }

2

Utilisez Crouton, c'est une bibliothèque Toast très flexible.

Croûton

Vous pouvez l'utiliser comme des toasts:

Crouton.makeText(context, "YOUR_MESSAGE", Style.INFO);

ou vous pouvez même aller un peu plus loin et le personnaliser davantage, comme régler l'heure à l'infini! par exemple ici, je veux afficher un message toast jusqu'à ce que l'utilisateur le reconnaisse en cliquant dessus.

private static void showMessage(final Activity context, MessageType type, String header, String message) {
    View v = context.getLayoutInflater().inflate(R.layout.toast_layout, null);
    TextView headerTv = (TextView) v.findViewById(R.id.toastHeader);
    headerTv.setText(header);
    TextView messageTv = (TextView) v.findViewById(R.id.toastMessage);
    messageTv.setText(message);
    ImageView toastIcon = (ImageView) v.findViewById(R.id.toastIcon);

    final Crouton crouton = getCrouton(context, v);
    v.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Crouton.hide(crouton);
        }
    });

    crouton.show();
}

private static Crouton getCrouton(final Activity context, View v) {
    Crouton crouton = Crouton.make(context, v);
    crouton.setConfiguration(new Configuration.Builder().setDuration(Configuration.DURATION_INFINITE).build());
    return crouton;
}

Disposition personnalisée qui sera gonflée pour le toast.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:animateLayoutChanges="true"
    android:background="@drawable/shadow_container"
    android:gravity="center_vertical"
    android:orientation="horizontal"
    android:padding="@dimen/default_margin"
    tools:ignore="Overdraw">

    <ImageView
        android:id="@+id/toastIcon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/default_spacing_full"
        android:layout_weight="1"
        android:orientation="vertical">

        <TextView
            android:id="@+id/toastHeader"
            style="@style/ItemText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/toastMessage"
            style="@style/ItemSubText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </LinearLayout>

</LinearLayout>

2

La durée du toast peut être piratée à l'aide d'un thread qui exécute le toast exclusivement. Cela fonctionne (exécute le toast pendant 10 secondes, modifiez le sommeil et le ctr à votre convenance):

final Toast toast = Toast.makeText(this, "Your Message", Toast.LENGTH_LONG);

Thread t = new Thread(){
    public void run(){
          int ctr = 0;
          try{
               while( ctr<10 ){
                    toast.show();
                    sleep(1000);
                    ctr++;
               }
          } catch (Exception e) {
               Log.e("Error", "", e);
          }
     }
 };
 t.start();

1

Un toast avec un arrière-plan et une vue personnalisés a fait l'affaire pour moi. Je l'ai testé sur la tablette Nexus 7 et je n'ai remarqué aucune animation de fondu de fondu lors du bouclage. Voici l'implémentation:

public static void customToast(Context context, String message, int duration) {

    for (int i = 0; i < duration; i++) {
        Toast toast = new Toast(context);
        toast.setDuration(Toast.LENGTH_LONG);
        toast.setGravity(Gravity.CENTER, 0, 0);
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = inflater.inflate(R.layout.toast_layout, null);
        TextView textViewToast = (TextView) view
                .findViewById(R.id.textViewToast);
        textViewToast.setText(message);
        toast.setView(view);
        toast.show();
    }

}

Voici le texte personnalisé utilisé dans le code ci-dessus:

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/textViewToast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/fragment_background"
android:padding="8dp"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="@color/blue" />

@ drawable / fragment_background fait que mes toasts ont un coin arrondi comme dans la version kitkat. Vous pouvez également ajouter d'autres vues dans le fichier. Toute modification pour amélioration et commentaires sont encouragés car je prévois de mettre en œuvre cela dans mon application en direct.


1

Planifiez un compte à rebours jusqu'à une date ultérieure, avec des notifications régulières à intervalles réguliers. Exemple d'affichage d'un compte à rebours de 30 secondes dans un champ de texte:

     nouveau CountDownTimer (30000, 1000) {

     public void onTick (long millisUntilFinished) {
         mTextField.setText ("secondes restantes:" + millisUntilFinished / 1000);
     }

     public void onFinish () {
         mTextField.setText ("terminé!");
     }
  }.début();



1

Ce texte disparaîtra dans 5 secondes.

    final Toast toast = Toast.makeText(getApplicationContext(), "My Text", Toast.LENGTH_SHORT);
    toast.show();

    Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
           @Override
           public void run() {
               toast.cancel(); 
           }
    }, 5000); // Change to what you want

Edit: Comme Itai Spector en commentaire l'a dit, il s'affichera environ 3,5 secondes, alors utilisez ce code:

    int toastDuration = 5000; // in MilliSeconds
    Toast mToast = Toast.makeText(this, "My text", Toast.LENGTH_LONG);
    CountDownTimer countDownTimer;
    countDownTimer = new CountDownTimer(toastDuration, 1000) {
        public void onTick(long millisUntilFinished) {
            mToast.show();
        }

        public void onFinish() {
            mToast.cancel();
        }
    };

    mToast.show();
    countDownTimer.start();

Je pense que ce texte disparaîtra après 3,5 secondes
Itai Spector

@ItaiSpector: Vérifiez mon nouveau code, s'il vous plaît.
Alireza Noorali

1

Non, et la plupart / tous les hacks répertoriés ici ne fonctionnent plus dans Android 9. Mais il existe une bien meilleure solution: si votre message doit traîner, utilisez une boîte de dialogue.

(new AlertDialog.Builder(this)).setTitle("Sorry!")
.setMessage("Please let me know by posting a beta comment on the play store .")
.setPositiveButton("OK", null).create().show();

Bien que ce ne soit pas la réponse que Hussein cherchait, c'est une meilleure option que tous ces «hacks»!
Danny EK van der Kolk

0

Une approche très simple pour créer un message légèrement plus long est la suivante:

private Toast myToast;

public MyView(Context context) {
  myToast = Toast.makeText(getContext(), "", Toast.LENGTH_LONG);
}

private Runnable extendStatusMessageLengthRunnable = new Runnable() {
  @Override
    public void run() {
    //Show the toast for another interval.
    myToast.show();
   }
}; 

public void displayMyToast(final String statusMessage, boolean extraLongDuration) {
  removeCallbacks(extendStatusMessageLengthRunnable);

  myToast.setText(statusMessage);
  myToast.show();

  if(extraLongDuration) {
    postDelayed(extendStatusMessageLengthRunnable, 3000L);
  }
}

Notez que l'exemple ci-dessus élimine l'option LENGTH_SHORT pour garder l'exemple simple.

Vous ne voudrez généralement pas utiliser un message Toast pour afficher des messages pendant de très longs intervalles, car ce n'est pas le but prévu de la classe Toast. Mais il y a des moments où la quantité de texte que vous devez afficher peut prendre plus de 3,5 secondes à l'utilisateur pour lire, et dans ce cas, une légère prolongation du temps (par exemple, à 6,5 secondes, comme indiqué ci-dessus) peut, à l'OMI, être utile et conforme à l'usage prévu.


0

Définit le toast à une période spécifique en milli-secondes:

public void toast(int millisec, String msg) {
    Handler handler = null;
    final Toast[] toasts = new Toast[1];
    for(int i = 0; i < millisec; i+=2000) {
        toasts[0] = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
        toasts[0].show();
        if(handler == null) {
            handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    toasts[0].cancel();
                }
            }, millisec);
        }
    }
}

0
  private Toast mToastToShow;
  public void showToast(View view) {
 // Set the toast and duration
 int toastDurationInMilliSeconds = 10000;
 mToastToShow = Toast.makeText(this, "Hello world, I am a toast.",  Toast.LENGTH_LONG);

 // Set the countdown to display the toast
 CountDownTimer toastCountDown;
 toastCountDown = new CountDownTimer(toastDurationInMilliSeconds, 1000 /*Tick duration*/) {
  public void onTick(long millisUntilFinished) {
     mToastToShow.show();
  }
  public void onFinish() {
     mToastToShow.cancel();
     }
    };

    // Show the toast and starts the countdown
     mToastToShow.show();
     toastCountDown.start();
      }

0

Après avoir échoué avec toutes les solutions disponibles, j'ai finalement eu une solution de contournement en utilisant la récursivité.

Code:

//Recursive function, pass duration in seconds
public void showToast(int duration) {
    if (duration <= 0)
        return;

    Toast.makeText(this, "Hello, it's a toast", Toast.LENGTH_LONG).show();
    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            showToast(duration-1);
        }
    }, 1000);
}

2
La plupart des solutions à cette question concernant l'appel répété de "show" pour garder le toast affiché le font avec la même instance de toast, alors que la vôtre crée en fait une nouvelle instance de toast toutes les secondes et spécifie que chacune doit être affichée pour le LONG durée (normalement 3,5 secondes). Non seulement cela est inefficace car vous continuez à créer des instances d'objets supplémentaires, mais Android place également les messages toast dans une file d'attente pour les afficher l'un après l'autre pendant leur durée spécifiée. Donc, si vous appelez cela avec une durée de 5, le message s'affichera pendant 17,5 secondes.
Niall

-1
Toast.makeText(this, "Text", Toast.LENGTH_LONG).show(); 
Toast.makeText(this, "Text", Toast.LENGTH_LONG).show();

Une solution très simple à la question. Deux ou trois fois, Toast durera plus longtemps. C'est le seul moyen de contourner.


Bien que cela semble pirater, mais appréciez la réflexion!
Sony Kadavan

pourquoi a voté contre une solution similaire mentionnée par @Arturo utilise la même astuce avec la boucle for
minable

Cette approche a fonctionné pour moi. Il serait bon d'entendre ceux qui ont voté contre pourquoi ils l'ont fait.
Christopher Mills

-8

Vous pouvez définir le temps souhaité en millisecondes dans la Toast.makeText();méthode comme ceci:

//40 seconds
long mToastLength = 40*1000 
//this toast will be displayed for 40 seconds.
Toast.makeText(this, "Hello!!!!!", mToastLength).show(); 

1
La réponse est correcte! L'API a été étendue à un moment donné pour permettre d'utiliser une valeur autre que LENGTH_LONG ou LENGTH_SHORT. I
rts

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.