Kann ein Android Toast länger sein als Toast.LENGTH_LONG?


263

Ist es bei Verwendung von setDuration () für einen Toast möglich, eine benutzerdefinierte Länge oder zumindest etwas länger als festzulegen Toast.LENGTH_LONG?


4
@Nicolae aus irgendeinem Grund haben Sie das toastTag entfernt? Es sieht relevant für die Frage aus.
Shadow Wizard ist Ear For You

2
@ShadowWizard Die Tags sollten meines Erachtens die Themen der Frage widerspiegeln, die von breitem Interesse sind. Wie zum Beispiel ist es mit Android markiert und so wird ein Android-Guru diese Frage finden. Toast hilft dieser Frage überhaupt nicht und scheint eher ein nutzloses Etikett zu sein. Wenn Toast ein gutes ist, weil die Frage über Tag in Android ist, dann war auch Länge ein gutes Tag. Hack, jedes Wort in der Frage sollte ein Tag sein ... Keine Respektlosigkeit, nur mein Punkt :)
Nicu Surdu

11
Ich benutze das toastTag um. Ich dachte, die Tags helfen beim Suchen und Sortieren und toastsind definitiv eine häufige Suche. androidund toastscheinen perfekt.
ChrisWilson4

Antworten:


142

Die Werte von LENGTH_SHORTund LENGTH_LONGsind 0 und 1. Dies bedeutet, dass sie eher als Flags als als tatsächliche Dauer behandelt werden, sodass ich nicht denke, dass es möglich sein wird, die Dauer auf etwas anderes als diese Werte festzulegen.

Wenn Sie eine Nachricht an den Benutzer für mehr angezeigt werden sollen, eine betrachten Statusleiste Benachrichtigung . Statusleistenbenachrichtigungen können programmgesteuert abgebrochen werden, wenn sie nicht mehr relevant sind.


1
Vielen Dank für den Vorschlag zur Statusleiste, aber ich gehe mit einer benutzerdefinierten Dialogaktivität.

337

Wenn Sie tiefer in den Android-Code eintauchen, finden Sie die Zeilen, die deutlich darauf hinweisen, dass wir die Dauer der Toast-Nachricht nicht ändern können.

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

und Standardwerte für die Dauer sind

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

4
Danke ... das war genau das, was ich brauchte.
Mcherm

3
Vielen Dank für die Veröffentlichung der Standardwerte! Ich hatte Angst, ich könnte sie nicht finden.
Amplify91

1
Ich suchte auch nach den Standard-Toastwerten, dies war der erste Treffer. Auf jeden Fall positiv bewertet. Vielen Dank!
Dave

120

Vielleicht möchten Sie versuchen:

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

die Zeit verdoppeln. Wenn Sie 3 anstelle von 2 angeben, verdreifacht sich die Zeit usw.


17
Nachricht blinkt :(
Deniz

61
Diese Lösung ist schlecht, weil zum Beispiel, wenn Sie die Aktivität vor dem Zeitpunkt des Toasts beenden, sie immer wieder
blinkt

@ Dwbrito: stimme voll und ganz zu und daher -1
Fahim Parkar

[+1] für die Antwort .... Das Abbrechen des Toasts kann Toast.cancel()an geeigneten Stellen erfolgen
Devrath

1
Ja, es kann implementiert werden, aber der Toast
blinkt

31

Wenn Sie möchten, dass a Toastbestehen bleibt, haben Sie festgestellt, dass Sie sich durch wiederholtes TimerAnrufen toast.show()(jede Sekunde oder so sollte dies tun) herumhacken können. Das Anrufen show()unterbricht nichts, wenn das Toastbereits angezeigt wird, aktualisiert jedoch die Zeit, die auf dem Bildschirm verbleibt.


3
Das Problem dabei ist, wenn der Benutzer den Bildschirm berührt, wird der Toast von Android ausgeblendet, dann aber vom Timer neu erstellt.
Violette Giraffe

2
@VioletGiraffe, die mit so etwas wie einer booleschen Flagge in Ihrer ViewGroup OnTouchVeranstaltung ziemlich trivial zu handhaben ist . Um dies zu optimieren, sollten Sie Ihren Timer wahrscheinlich so nahe wie möglich an der tatsächlichen Zeit wiederholen lassen, die Toastauf dem Bildschirm angezeigt wird (3,5 Sekunden für lange, 2 Sekunden für kurze)
Syklon

18

Ich habe eine benutzerdefinierte Toast-Klasse entwickelt, mit der Sie Toast für eine gewünschte Dauer (in Millisekunden) anzeigen können.

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: Fenster kann nicht hinzugefügt werden - Token null ist ungültig; Läuft Ihre Aktivität?
Ahamadullah Saikat

13

Ich habe dafür eine Helferklasse programmiert. Sie können den Code unter github sehen: https://github.com/quiqueqs/Toast-Expander/blob/master/src/com/thirtymatches/toasted/ToastedActivity.java

So würden Sie einen Toast für 5 Sekunden (oder 5000 Millisekunden) anzeigen:

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

Danke und schön, aber wie können wir zum Beispiel den Thread onDestroy stoppen? Ich habe versucht, dies zu tun, bin mir aber nicht sicher: public static void cancel (Toast mytoast) {if (null! = T) t.stop (); mytoast.cancel (); }
Hornetbzz

10

Ich weiß, dass ich etwas spät dran bin, aber ich habe die Antwort von Regis_AG in eine Hilfsklasse eingepackt und es funktioniert großartig.

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

Gehen Sie in Ihrem Anwendungscode einfach so vor:

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

Das funktioniert tatsächlich! Aber wie können Sie es anpassbar und berührbar machen?
Android-Entwickler

Entschuldigung für diese Neulingsfrage, aber wenn ich die obige Toaster-Klasse erstelle, heißt es, dass das Symbol 'App' in der Zeile nicht aufgelöst werden kann. final Toast t = Toast.makeText (App.context (), Text, Toast.LENGTH_SHORT); Danke und Entschuldigung.
Brian Fleming

Oh, tut mir leid! App.context () ist im Grunde ein benutzerdefinierter Code, den ich geschrieben habe, um bequem von überall auf den ApplicationContext zuzugreifen, ohne ihn weiterzugeben. Kein Muster, das Sie für viele Dinge verwenden würden, aber ich fand, dass es für ApplicationContext sinnvoll ist. Möglicherweise möchten Sie dieses Snippet bearbeiten, um ApplicationContext als Argument an die Methode zu übergeben.
Chris Aitchison

9

Ich weiß, dass die Antwort ziemlich spät ist. Ich hatte das gleiche Problem und entschied mich, meine eigene Version von Bare Bones Toast zu implementieren, nachdem ich den Quellcode von Android für Toast untersucht hatte.

Grundsätzlich müssen Sie einen neuen Fenstermanager erstellen und das Fenster mit einem Handler für die gewünschte Dauer ein- und ausblenden

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

Nach der Initialisierung des Layouts können Sie Ihre eigenen Ein- und Ausblendmethoden verwenden

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

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

Jetzt müssen Sie nur noch zwei ausführbare Threads hinzufügen, die handleShow () und handleHide () aufrufen, die Sie an den Handler senden können.

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

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

und der letzte Teil

public void show() {

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

}

Dies war eine schnelle und schmutzige Implementierung. Ich habe keine Leistung berücksichtigt.


1
Ich habe versucht, es auszuführen (einschließlich des Aufrufs von "show ()"), aber es wird nichts angezeigt (getestet auf Android 7.1). Ich denke du vermisst etwas. Wo ist hier der Teil, der verhindert, dass die Ansicht entfernt wird, da ein Toast nach kurzer Zeit verschwindet?
Android-Entwickler

8

Toastanzeige LONG_DELAY für 3,5 Sekunden und Toastanzeige SHORT_DELAY für 2 Sekunden .

Toast verwendet intern INotificationManager und ruft die enqueueToast-Methode jedes Mal auf, wenn eine Toast.show () aufgerufen wird.

Wenn Sie die Show () zweimal mit SHORT_DELAY aufrufen, wird derselbe Toast erneut in die Warteschlange gestellt. Es wird 4 Sekunden lang (2 Sekunden + 2 Sekunden) angezeigt .

Wenn Sie die Show () mit LONG_DELAY zweimal aufrufen, wird derselbe Toast erneut in die Warteschlange gestellt. Es wird 7 Sekunden lang angezeigt (3,5 Sekunden + 3,5 Sekunden).


6

Hier ist eine benutzerdefinierte Toast-Klasse, die ich mit dem obigen Code erstellt habe:

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

Wenn Sie einen langen Toast benötigen, gibt es eine praktische Alternative, aber Ihr Benutzer muss auf eine OK-Schaltfläche klicken, damit er verschwindet. Sie können einen AlertDialog wie folgt verwenden:

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

Wenn Sie eine lange Nachricht haben, wissen Sie wahrscheinlich nicht, wie lange es dauern wird, bis Ihr Benutzer die Nachricht gelesen hat. Daher ist es manchmal eine gute Idee, von Ihrem Benutzer zu verlangen, dass er auf eine OK-Schaltfläche klickt, um fortzufahren. In meinem Fall verwende ich diese Technik, wenn ein Benutzer auf ein Hilfesymbol klickt.


1
Dies ist klug, kann aber nicht in so etwas wie a implementiert werden Service, wo es keine Benutzeroberfläche gibt.
Mike47

@mikejeep Eigentlich habe ich kürzlich ein Beispiel von Google gesehen, das einen Dialog ohne Aktivität zeigt: developer.android.com/samples/AppShortcuts/index.html
Android-Entwickler

5

Wie von anderen erwähnt, können Android Toasts entweder LENGTH_LONG oder LENGTH_SHORT sein. Daran führt kein Weg vorbei, und Sie sollten auch keinem der veröffentlichten "Hacks" folgen.

Der Zweck von Toasts besteht darin, "nicht wesentliche" Informationen anzuzeigen. Aufgrund ihrer anhaltenden Wirkung können Nachrichten weit aus dem Zusammenhang gerissen werden, wenn ihre Dauer einen bestimmten Schwellenwert überschreitet. Wenn Standard-Toasts so geändert wurden, dass sie länger als LENGTH_LONG angezeigt werden können, bleibt die Nachricht auf dem Bildschirm, bis der Anwendungsprozess beendet wird, da dem WindowManager Toastansichten hinzugefügt werden und keine ViewGroup in Ihrer App. Ich würde annehmen, dass dies der Grund ist, warum es fest codiert ist.

Wenn Sie unbedingt eine Nachricht im Toaststil anzeigen müssen, die länger als dreieinhalb Sekunden dauert, empfehle ich, eine Ansicht zu erstellen, die an den Inhalt der Aktivität angehängt wird. Auf diese Weise verschwindet sie, wenn der Benutzer die Anwendung beendet. Meine SuperToasts- Bibliothek befasst sich mit diesem und vielen anderen Problemen. Sie können es gerne verwenden! Sie wären höchstwahrscheinlich an der Verwendung von SuperActivityToasts interessiert


4

Verwenden Sie einfach SuperToast , um in jeder Situation einen eleganten Toast zuzubereiten . Machen Sie Ihren Toast bunt . Bearbeiten Sie Ihre Schriftfarbe und auch deren Größe . Hoffe, es wird alles in einem für Sie sein.



3

Hier ist eine sehr einfache Methode, die für mich funktioniert hat:

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

Die Dauer von LENGTH_SHORT beträgt 2 Sekunden und LENGTH_LONG 3,5 Sekunden. Hier wird die Toastnachricht 6 Sekunden lang angezeigt, da sie in einer for-Schleife eingeschlossen ist. Ein Nachteil dieser Methode ist jedoch, dass nach jeweils 2 Sekunden ein kleiner Fading-Effekt auftreten kann. aber es ist nicht viel auffällig. Hoffe es ist hilfreich


2

Der Benutzer kann die Dauer des Toasts nicht festlegen. da die ScheduleTimeoutLocked () -Funktion von NotificationManagerService die Felddauer nicht verwendet. Der Quellcode lautet wie folgt.

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

Verwenden Sie Crouton, es ist eine sehr flexible Toast-Bibliothek.

Crouton

Sie können es wie Toast verwenden:

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

oder Sie können sogar ein wenig tiefer gehen und es mehr anpassen, wie die Zeit auf unendlich einstellen! Zum Beispiel möchte ich hier eine Toastnachricht anzeigen, bis der Benutzer sie durch Klicken bestätigt.

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

Kundenspezifisches Layout, das für den Toast aufgeblasen wird.

<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

Die Toastdauer kann mit einem Thread gehackt werden, der ausschließlich den Toast ausführt. Dies funktioniert (führt den Toast 10 Sekunden lang aus, ändert den Schlaf und die Steuerung nach Ihren Wünschen):

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

Ein Toast mit benutzerdefiniertem Hintergrund und Ansicht hat den Trick für mich getan. Ich habe es im Nexus 7 Tablet getestet und beim Looping keine Fadein-Fadeout-Animation festgestellt. Hier ist die Implementierung:

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

}

Hier ist die benutzerdefinierte Textansicht, die im obigen Code verwendet wird:

<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 lässt meinen Toast wie in der Kitkat-Version eine abgerundete Ecke haben. Sie können der Datei auch andere Ansichten hinzufügen. Änderungen und Kommentare sind erwünscht, da ich dies in meiner Live-App implementieren möchte.


1

Planen Sie einen Countdown bis zu einem späteren Zeitpunkt mit regelmäßigen Benachrichtigungen in Intervallen auf dem Weg. Beispiel für die Anzeige eines 30-Sekunden-Countdowns in einem Textfeld:

     neuer CountDownTimer (30000, 1000) {

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

     public void onFinish () {
         mTextField.setText ("erledigt!");
     }}
  }.Anfang();



1

Dieser Text verschwindet in 5 Sekunden.

    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

Bearbeiten: Wie Itai Spector im Kommentar sagte, wird es ungefähr 3,5 Sekunden lang angezeigt. Verwenden Sie also diesen 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();

Ich denke, dieser Text wird nach 3,5 Sekunden verschwinden
Itai Spector

@ItaiSpector: Überprüfen Sie bitte meinen neuen Code.
Alireza Noorali

1

Nein, und die meisten / alle hier aufgeführten Hacks funktionieren nicht mehr in Android 9. Es gibt jedoch eine viel bessere Lösung: Wenn Ihre Nachricht herumhängen muss, verwenden Sie ein Dialogfeld.

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

Obwohl dies nicht die Antwort ist, nach der Hussein gesucht hat, ist es eine bessere Option als all diese "Hacks"!
Danny EK van der Kolk

0

Ein sehr einfacher Ansatz zum Erstellen einer etwas längeren Nachricht lautet wie folgt:

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

Beachten Sie, dass im obigen Beispiel die Option LENGTH_SHORT entfernt wird, um das Beispiel einfach zu halten.

Im Allgemeinen möchten Sie keine Toast-Nachricht verwenden, um Nachrichten für sehr lange Intervalle anzuzeigen, da dies nicht der beabsichtigte Zweck der Toast-Klasse ist. Es gibt jedoch Situationen, in denen die Anzeige der Textmenge, die Sie anzeigen müssen, länger als 3,5 Sekunden dauern kann. In diesem Fall kann eine geringfügige Verlängerung der Zeit (z. B. auf 6,5 Sekunden, wie oben gezeigt), IMO, hilfreich sein und im Einklang mit der beabsichtigten Verwendung.


0

Stellt den Toast in Millisekunden auf einen bestimmten Zeitraum ein:

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

Nachdem ich mit jeder verfügbaren Lösung versagt hatte, hatte ich endlich eine Problemumgehung mit Rekursion.

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
Die meisten Lösungen zu dieser Frage, die sich auf das wiederholte Aufrufen von "show" beziehen, um den Toast anzuzeigen, erfolgen mit derselben Toastinstanz, während Ihre tatsächlich jede Sekunde eine neue Toastinstanz erstellt und angibt, dass jede für den LONG angezeigt werden soll Dauer (normalerweise 3,5 Sekunden). Dies ist nicht nur ineffizient, weil Sie ständig zusätzliche Objektinstanzen erstellen, sondern Android stellt auch Toastnachrichten in eine Warteschlange, die für die angegebene Dauer nacheinander angezeigt werden. Wenn Sie dies also mit einer Dauer von 5 aufrufen, wird die Nachricht tatsächlich 17,5 Sekunden lang angezeigt.
Niall

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

Eine sehr einfache Lösung für die Frage. Zweimal oder dreifach halten Toast länger. Es ist der einzige Weg herum.


Klingt zwar hack, aber schätze das Denken!
Sony Kadavan

Warum eine ähnliche Lösung, die von @Arturo erwähnt wurde, herabgestimmt hat, verwendet denselben Trick mit der for-Schleife
schäbig

Dieser Ansatz hat bei mir funktioniert. Es wäre gut, von denen zu hören, die abgestimmt haben, warum sie das getan haben.
Christopher Mills

-8

Sie können die gewünschte Zeit in Millisekunden Toast.makeText();wie folgt einstellen :

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

1
Die Antwort ist RICHTIG! Die API wurde zu einem bestimmten Zeitpunkt erweitert, um die Verwendung eines anderen Werts als LENGTH_LONG oder LENGTH_SHORT zu ermöglichen. I
rts

Das glaube ich nicht. Schauen Sie sich android.googlesource.com/platform/frameworks/base/+/…
AntiCZ
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.