Un toast Android può essere più lungo di Toast.LENGTH_LONG?


263

Quando si utilizza setDuration () per un Toast, è possibile impostare una lunghezza personalizzata o almeno qualcosa di più lungo di Toast.LENGTH_LONG?


4
@Nicolae qualche motivo per cui hai rimosso il toasttag? Sembra rilevante per la domanda ..
Shadow Wizard è Ear For You

2
@ShadowWizard I tag, mi sembra, dovrebbero riflettere gli argomenti della domanda che è di grande interesse. Come ad esempio, è taggato Android e quindi un guru Android troverà questa domanda. Toast non aiuta affatto questa domanda e sembra più un tag inutile. Se il brindisi è positivo, poiché la domanda riguarda Tag in Android, anche la lunghezza era un buon tag. Hack, ogni parola nella domanda dovrebbe essere un tag ... Nessuna mancanza di rispetto, solo il mio punto :)
Nicu Surdu

11
Uso il toasttag per. Ho pensato che i tag fossero lì per aiutare la ricerca e l'ordinamento ed toastè sicuramente una ricerca comune. androide toastsembra perfetto.
ChrisWilson4,

Risposte:


142

I valori di LENGTH_SHORTe LENGTH_LONGsono 0 e 1. Ciò significa che sono trattati come flag anziché come durate effettive, quindi non penso che sarà possibile impostare la durata su qualcosa di diverso da questi valori.

Se si desidera visualizzare un messaggio all'utente più a lungo, prendere in considerazione una notifica sulla barra di stato . Le notifiche della barra di stato possono essere annullate a livello di codice quando non sono più pertinenti.


1
Grazie per il suggerimento sulla barra di stato, ma vado con un'attività di dialogo personalizzata.

337

Se approfondisci il codice Android, puoi trovare le righe che indicano chiaramente che non possiamo modificare la durata del messaggio Toast.

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

e i valori predefiniti per la durata sono

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

4
Grazie ... questo era ESATTAMENTE quello di cui avevo bisogno.
mcherm

3
Grazie per aver pubblicato i valori predefiniti! Avevo paura di non riuscire a trovarli.
Amplifica il

1
Stavo cercando anche i valori di toast predefiniti, questo è stato il primo successo. Decisamente votato. Grazie!
Dave,

120

Puoi provare:

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

raddoppiare il tempo. Se si specifica 3 invece del 2, triplicherà il tempo ... ecc.


17
il messaggio lampeggia :(
Deniz,

61
Questa soluzione è negativa perché, ad esempio, se si interrompe l'attività prima del brindisi, lampeggerà più volte ...
dwbrito,

@dwbrito: totalmente d'accordo e quindi -1
Fahim Parkar,

[+1] per la risposta .... L'annullamento del toast può essere gestito utilizzando Toast.cancel()in luoghi appropriati
Devrath

1
Sì, può essere implementato, ma il brindisi lampeggia tanto quanto viene specificato il conteggio
HendraWD

31

Se si desidera una Toasta persistere, ho trovato è possibile incidere il vostro modo intorno ad esso per avere una Timerchiamata toast.show()più volte (ogni secondo o giù di lì dovrebbe fare). La chiamata show()non interrompe nulla se Toastè già visualizzato, ma aggiorna la quantità di tempo che rimane sullo schermo.


3
Il problema è che se l'utente tocca lo schermo il toast verrà nascosto da Android ma ricreato dal timer.
Violet Giraffe

2
@VioletGiraffe è abbastanza banale da gestire con qualcosa come una bandiera booleana nel tuo ViewGroup OnTouchevento. Per ottimizzarlo, probabilmente dovresti ripetere il tuo timer il più vicino possibile al momento in cui Toastviene mostrato sullo schermo (3,5 secondi per un lungo, 2 secondi per un breve)
Syklon

18

Ho sviluppato un corso Toast personalizzato con il quale puoi mostrare Toast per la durata desiderata (in Milli secondi)

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: impossibile aggiungere la finestra - token null non è valido; la tua attività è attiva?
Ahamadullah Saikat

13

Ho programmato una classe di supporto per farlo. Puoi vedere il codice su github: https://github.com/quiqueqs/Toast-Expander/blob/master/src/com/thirtymatches/toasted/ToastedActivity.java

Ecco come visualizzeresti un brindisi per 5 secondi (o 5000 millisecondi):

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

Grazie e Nizza, ma come possiamo interrompere il thread su Distruggi per esempio? Ho provato a farlo, ma non sono sicuro: public static void cancel (Toast mytoast) {if (null! = T) t.stop (); mytoast.cancel (); }
hornetbzz,

10

So di essere un po 'in ritardo, ma ho preso la risposta di Regis_AG e l'ho inserita in una classe di supporto e funziona benissimo.

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

Nel codice dell'applicazione, fai semplicemente una cosa del genere:

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

Questo funziona davvero! ma come puoi renderlo personalizzabile e tangibile?
sviluppatore Android

Ci scusiamo per questa domanda da principiante, ma quando creo la classe Toaster sopra, dice che non è possibile risolvere il simbolo "App" nella riga. toast finale t = Toast.makeText (App.context (), testo, Toast.LENGTH_SHORT); Grazie e scuse.
Brian Fleming,

oh, scusa per quello! App.context () è fondamentalmente un pezzo di codice personalizzato che avevo scritto per accedere a ApplicationContext comodamente da qualsiasi luogo senza passarlo in giro. Non è un modello che useresti per molte cose, ma ho scoperto che aveva senso per ApplicationContext. Potresti voler modificare questo frammento per passare ApplicationContext nel metodo come argomento.
Chris Aitchison,

9

So che la risposta è abbastanza tardi .. Ho avuto lo stesso problema e ho deciso di implementare la mia versione di bare bones Toast, dopo aver esaminato il codice sorgente di Android per toast.

Fondamentalmente è necessario creare un nuovo gestore di finestre e mostrare e nascondere la finestra per la durata desiderata utilizzando un gestore

 //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;

Dopo l'inizializzazione del layout è possibile utilizzare i propri metodi Nascondi e Mostra

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

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

Ora tutto ciò che serve è aggiungere due thread eseguibili che chiamano handleShow () e handleHide () che è possibile pubblicare sul gestore.

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

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

e la parte finale

public void show() {

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

}

Questa è stata un'implementazione rapida e sporca. Non ho preso in considerazione alcuna prestazione.


1
Ho provato a eseguirlo (inclusa la chiamata a "show ()") ma non appare nulla (testato su Android 7.1). Penso che ti manchi qualcosa. Inoltre, dov'è la parte qui che impedisce la rimozione della vista, poiché un brindisi scompare dopo poco tempo?
sviluppatore Android

8

LAST_DELAY visualizzazione toast per 3,5 secondi e SHORT_DELAY visualizzazione toast per 2 secondi .

Toast usa internamente INotificationManager e chiama il suo metodo enqueueToast ogni volta che viene chiamato Toast.show ().

Chiama lo spettacolo () con SHORT_DELAY due volte accoda di nuovo lo stesso brindisi. verrà visualizzato per 4 secondi (2 secondi + 2 secondi).

allo stesso modo, chiamare lo spettacolo () con LONG_DELAY due volte accoda di nuovo lo stesso brindisi. verrà visualizzato per 7 secondi (3,5 secondi + 3,5 secondi)


6

Ecco una classe Toast personalizzata che ho creato utilizzando il codice sopra:

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

Se hai bisogno di un lungo toast, c'è un'alternativa pratica, ma richiede all'utente di fare clic su un pulsante OK per farlo sparire. È possibile utilizzare un AlertDialog in questo modo:

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

Se hai un messaggio lungo, probabilmente non sai quanto tempo impiegherà il tuo utente a leggere il messaggio, quindi a volte è una buona idea richiedere all'utente di fare clic su un pulsante OK per continuare. Nel mio caso, utilizzo questa tecnica quando un utente fa clic sull'icona di una guida.


1
Questo è intelligente, ma non può essere implementato in qualcosa di simile a un Service, dove non esiste un'interfaccia utente.
mike47,

@mikejeep In realtà, recentemente ho visto un esempio di Google, che mostra una finestra di dialogo senza attività: developer.android.com/samples/AppShortcuts/index.html
sviluppatore Android

5

Come accennato da altri toast Android può essere LENGTH_LONG o LENGTH_SHORT. Non c'è modo di aggirare questo, né dovresti seguire nessuno degli "hack" pubblicati.

Lo scopo di Toasts è quello di visualizzare informazioni "non essenziali" e, a causa del loro effetto persistente, i messaggi possono essere messi fuori contesto se la loro durata supera una certa soglia. Se i toast di riserva sono stati modificati in modo che possano essere visualizzati più a lungo di LENGTH_LONG, il messaggio rimarrà sullo schermo fino a quando il processo dell'applicazione non verrà terminato poiché le visualizzazioni di toast vengono aggiunte al WindowManager e non a un ViewGroup nella tua app. Suppongo che sia per questo che è hard coded.

Se devi assolutamente mostrare un messaggio in stile brindisi per più di tre secondi e mezzo, ti consiglio di creare una vista che si attacca al contenuto dell'Attività, in questo modo scomparirà quando l'utente esce dall'applicazione. La mia libreria SuperToasts tratta questo problema e molti altri, sentiti libero di usarlo! Molto probabilmente ti interesserebbe usare SuperActivityToasts


4

Usa semplicemente SuperToast per fare un brindisi elegante in ogni situazione. Rendi colorato il tuo toast . Modifica il colore del carattere e anche le sue dimensioni . Spero che sarà tutto in uno per te.



3

Ecco un metodo molto semplice che ha funzionato per me:

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

La durata di LENGTH_SHORT è di 2 secondi e LENGTH_LONG è di 3,5 secondi, qui il messaggio di brindisi verrà mostrato per 6 secondi poiché è racchiuso in un ciclo for. Ma uno svantaggio di questo metodo è che ogni 2 secondi può verificarsi un piccolo effetto di dissolvenza. ma non è molto evidente. Spero sia utile


2

L'utente non può personalizzare la durata del Toast. perché la funzione scheduleTimeoutLocked () di NotificationManagerService non utilizza la durata del campo. il codice sorgente è il seguente.

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

Usa Crouton, è una libreria Toast molto flessibile.

Crostino

Puoi usarlo proprio come toast:

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

oppure puoi anche andare un po 'più a fondo e personalizzarlo di più, come impostare il tempo su infinito! ad esempio qui voglio mostrare un messaggio di brindisi fino a quando l'utente non lo riconosce facendo clic su di esso.

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

Layout personalizzato che verrà gonfiato per il brindisi.

<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 durata del toast può essere compromessa utilizzando un thread che esegue esclusivamente il toast. Funziona (esegue il brindisi per 10 secondi, modifica sleep e ctr a tuo piacimento):

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 brindisi con sfondo e vista personalizzati mi ha aiutato. L'ho provato su un tablet Nexus 7 e non ho notato animazioni di dissolvenza in dissolvenza durante il looping. Ecco l'implementazione:

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

}

Ecco la visualizzazione di testo personalizzata utilizzata nel codice sopra:

<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 sta facendo in modo che i miei toast abbiano angoli arrotondati come nella versione kitkat. Puoi anche aggiungere altre viste nel file. Eventuali modifiche per miglioramenti e commenti sono incoraggiati mentre sto pianificando di implementarlo nella mia app live.


1

Pianifica un conto alla rovescia fino a un momento futuro, con notifiche regolari a intervalli lungo il percorso. Esempio di visualizzazione di un conto alla rovescia di 30 secondi in un campo di testo:

     nuovo CountDownTimer (30000, 1000) {

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

     public void onFinish () {
         mTextField.setText ( "fatto!");
     }
  }.inizio();



1

Questo testo scomparirà tra 5 secondi.

    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

Modifica: come ha detto Itai Spector nel commento, verrà mostrato per circa 3,5 secondi, quindi usa questo codice:

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

Penso che questo testo scomparirà dopo 3,5 secondi
Itai Spector,

@ItaiSpector: controlla il mio nuovo codice, per favore.
Alireza Noorali,

1

No, e la maggior parte / tutti gli hack elencati qui non funzionano più in Android 9. Ma c'è una soluzione molto migliore: se il tuo messaggio deve rimanere in giro, usa una finestra di dialogo.

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

Anche se questa non è la risposta che Hussein stava cercando, è un'opzione migliore di tutti quegli "hack"!
Danny EK van der Kolk,

0

Un approccio molto semplice alla creazione di un messaggio leggermente più lungo è il seguente:

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

Si noti che l'esempio sopra elimina l'opzione LENGTH_SHORT per semplificare l'esempio.

In genere non si desidera utilizzare un messaggio Toast per visualizzare i messaggi per intervalli molto lunghi, poiché non è lo scopo previsto della classe Toast. Ma ci sono momenti in cui la quantità di testo che è necessario visualizzare potrebbe richiedere all'utente più di 3,5 secondi per la lettura e in tal caso una leggera estensione del tempo (ad esempio, a 6,5 ​​secondi, come mostrato sopra) può, IMO, essere utile e coerente con l'uso previsto.


0

Imposta il brindisi su un periodo specifico in milli-secondi:

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

Dopo aver fallito con ogni soluzione disponibile, ho finalmente avuto una soluzione utilizzando la ricorsione.

Codice:

//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 maggior parte delle soluzioni su questa domanda relative alla chiamata ripetuta di "show" per mantenere il toast visualizzato lo stanno facendo con la stessa istanza di toast, mentre la tua sta effettivamente creando una nuova istanza di toast ogni secondo e specificando che ognuno dovrebbe essere mostrato per il LONG durata (normalmente 3,5 secondi). Non solo è inefficiente perché continui a creare istanze di oggetti extra, ma anche Android mette i messaggi di brindisi in una coda per essere mostrati uno dopo l'altro per la durata specificata. Quindi, se lo hai chiamato con una durata di 5, il messaggio verrebbe effettivamente mostrato per 17,5 secondi.
Niall,

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

Una soluzione molto semplice alla domanda. Due o tre volte faranno durare più a lungo Toast. È l'unico modo per aggirare.


Anche se sembra hack, ma apprezza il pensiero!
Sony Kadavan,

perché downvoted una soluzione simile menzionata da @Arturo usa lo stesso trucco con il ciclo for
squallido

Questo approccio ha funzionato per me. Sarebbe bello avere notizie di coloro che hanno votato perché non lo hanno fatto.
Christopher Mills,

-8

È possibile impostare il tempo desiderato in millisecondi nel Toast.makeText();metodo in questo modo:

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

1
La risposta è CORRETTA! L'API è stata estesa in un determinato momento per consentire l'utilizzo di un valore diverso da LENGTH_LONG o LENGTH_SHORT. I
RTS

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.