Can an Android Toast be longer than Toast.LENGTH_LONG?
Asked Answered
K

27

303

When using setDuration() for a Toast, is it possible to set a custom length or at least something longer than Toast.LENGTH_LONG?

Kumiss answered 8/2, 2010 at 9:27 Comment(3)
@Nicolae any reason you removed the toast tag? It looks relevant to the question..Cindycine
@ShadowWizard The tags, seems to me, should reflect the topics of the question that is of broad interest. Like for example, it's tagged android and so an android guru will find this question. Toast doesn't help this question at all and seems more like a useless tag. If toast is a good that, because the question is about Tag in Android, then also length was a good tag. Hack, every word in the question should be a tag ... No disrespect, just making my point :)Connubial
I use the toast tag to. I thought the tags were there to help for searching and sorting and toast is definitely a common search. android and toast seem perfect.Delict
B
157

The values of LENGTH_SHORT and LENGTH_LONG are 0 and 1. This means they are treated as flags rather than actual durations so I don't think it will be possible to set the duration to anything other than these values.

If you want to display a message to the user for longer, consider a Status Bar Notification. Status Bar Notifications can be programmatically canceled when they are no longer relevant.

Buerger answered 8/2, 2010 at 11:43 Comment(2)
Thanks for the suggestion about the status bar, but im going with a custom dialog activity.Kumiss
that's an interesting idea but rather different than a toast. A dialog box is a much better choice (like the example I give below).Fullerton
R
374

If you dig deeper in android code, you can find the lines that clearly indicate, that we cannot change the duration of Toast message.

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

and default values for duration are

private static final int LONG_DELAY = 3500; // 3.5 seconds
private static final int SHORT_DELAY = 2000; // 2 seconds
Return answered 22/2, 2011 at 14:42 Comment(3)
Thank you for posting the default values! I was afraid I wouldn't be able to find them.Baize
I was looking for the default toast values as well, this was the first hit. Definitely upvoted. Thanks!Angadreme
this is true. the solution is to look for something other than a toast, like a dialog boxFullerton
B
157

The values of LENGTH_SHORT and LENGTH_LONG are 0 and 1. This means they are treated as flags rather than actual durations so I don't think it will be possible to set the duration to anything other than these values.

If you want to display a message to the user for longer, consider a Status Bar Notification. Status Bar Notifications can be programmatically canceled when they are no longer relevant.

Buerger answered 8/2, 2010 at 11:43 Comment(2)
Thanks for the suggestion about the status bar, but im going with a custom dialog activity.Kumiss
that's an interesting idea but rather different than a toast. A dialog box is a much better choice (like the example I give below).Fullerton
A
128

You may want to try:

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

to double the time. If you specify 3 instead the 2 it will triple the time..etc.

Alyss answered 16/6, 2011 at 18:40 Comment(11)
This solution is bad because, e.g., if you quit the activity before the time of the toast, it will be blinking over and over...Sumrall
@Sumrall : totally agree and hence -1Gisele
[+1] for the answer .... Canceling the toast can be handled by using Toast.cancel() in appropriate placesGerge
Yes it can be implemented, but the toast will be blinking as much as you specify the countRhabdomancy
This is the best DIY answer ever ahah - Didn't do it.Actuality
Wow! Why didn't I think of that hahaThylacine
Tricky hack , but if I want to reduce it , how can I do that ?Selfappointed
I don't know if this worked before, but it doesn't seem to work now.Liar
This shouldn't work and didn't for me. A subsequent toast show just immediately replaces the previous show. You need a delay timer between shows. Did toast shows line up nicely in a queue back in 2011 when this answer was given?Vertu
This no longer works with more recent android (10,9, at the least). Use a dialog box, like I suggest below).Fullerton
It is working in Android 10 but not in 9, any solution for this?Tablecloth
Q
31

If you want a Toast to persist, I found you can hack your way around it by having a Timer call toast.show() repeatedly (every second or so should do). Calling show() doesn't break anything if the Toast is already showing, but it does refresh the amount of time it stays on the screen.

Quickstep answered 12/8, 2010 at 18:35 Comment(2)
The problem with this is if user touches screen the toast will be hidden by Android but then recreated by timer.Monoploid
@VioletGiraffe that's pretty trivial to handle with something like a boolean flag in your ViewGroup OnTouch event. To optimize this you should probably make your timer repeat as close to the actual time the Toast is shown on screen (3.5 seconds for long, 2 seconds for short)Partheniaparthenocarpy
F
16

I have developed a Custom Toast class with which you can show Toast for a desired amount of duration (in Milli seconds)

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);
        }
    }
}
Fable answered 18/1, 2014 at 11:37 Comment(1)
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?Reynoso
M
14

LONG_DELAY toast display for 3.5 sec and SHORT_DELAY toast display for 2 sec.

Toast internally use INotificationManager and calls it's enqueueToast method every time a Toast.show() is called.

Call the show() with SHORT_DELAY twice will enqueue same toast again. it will display for 4 sec ( 2 sec + 2 sec).

similarly, call the show() with LONG_DELAY twice will enqueue same toast again. it will display for 7 sec ( 3.5 sec + 3.5 sec)

Marianomaribel answered 28/8, 2015 at 7:14 Comment(1)
This hack doesn't seem to work any longer.Fullerton
C
13

I've coded up a helper class for doing this. You can see the code at github: https://github.com/quiqueqs/Toast-Expander/blob/master/src/com/thirtymatches/toasted/ToastedActivity.java

This is how you'd display a toast for 5 seconds (or 5000 milliseconds):

Toast aToast = Toast.makeText(this, "Hello World", Toast.LENGTH_SHORT);
ToastExpander.showFor(aToast, 5000);
Commodus answered 3/1, 2012 at 2:9 Comment(1)
Thx and Nice but how can we stop the thread onDestroy for example ? I've tried to do that but not sure : public static void cancel(Toast mytoast) { if (null != t) t.stop(); mytoast.cancel(); }Forsook
S
11

I know I am a bit late, but I took Regis_AG's answer and wrapped it in a helper class and it works great.

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

In your application code, just do something like this:

    Toaster.makeLongToast("Toasty!", 8000);
Sideslip answered 2/2, 2015 at 0:31 Comment(3)
This actually works! but how can you make it customizable, and touchable?Mcgaw
Sorry for this newbie question, but when I create the above Toaster class, it says it can not resolve symbol 'App' in the line . final Toast t = Toast.makeText(App.context(), text, Toast.LENGTH_SHORT); Thanks, and apologies.Tripodic
oh, sorry about that! App.context() is basically a piece of custom code I had written to access the ApplicationContext conveniently from anywhere without passing it around. Not a pattern you'd use for many things, but I found that it made sense for ApplicationContext. You may want to edit this snippet to pass ApplicationContext into the method as an argument.Sideslip
W
9

I know the answer is quite late .. I had the very same issue and decided to implement my own version of bare bones Toast , after looking into android's source code for toast .

Basically you need to create a new Window manager , and show and hide the window for the desired duration duration using a handler

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

After initialization of the layout you can use your own hide and show methods

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

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

Now all you need is to add two runnable threads which calls the handleShow() and the handleHide() which you could post to the Handler.

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

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

and the final part

public void show() {

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

}

This was a quick and dirty implementation .. Have not taken any performance into consideration .

Westfahl answered 1/11, 2012 at 18:41 Comment(1)
I tried to run it (including call to "show()") but nothing appears (tested on Android 7.1) . I think you miss something. Also, where is the part here that prevents the view from being removed, as a toast disappears after a short time ?Mcgaw
M
7

If you need a long Toast, there's a practical alternative, but it requires your user to click on an OK button to make it go away. You can use an AlertDialog like this:

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

If you have a long message, chances are, you don't know how long it will take for your user to read the message, so sometimes it is a good idea to require your user to click on an OK button to continue. In my case, I use this technique when a user clicks on a help icon.

Mccollum answered 16/11, 2013 at 1:20 Comment(3)
This is smart, but cannot be implemented in something like a Service, where there is no UI.Ironware
@mikejeep Actually, I've recently seen an example by Google, showing a dialog without an activity: developer.android.com/samples/AppShortcuts/index.htmlMcgaw
This is exactly what I'm looking for. It worked like charm at my Expandible view content. Thank you so much after 10+ years <3Ichabod
E
6

Here is a custom Toast class I made using the above code:

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();  
    }
}
Eigenfunction answered 14/11, 2011 at 17:9 Comment(0)
W
5

As mentioned by others Android Toasts can either be LENGTH_LONG or LENGTH_SHORT. There is no way around this, nor should you follow any of the 'hacks' posted.

The purpose of Toasts are to display "non-essential" information and due to their lingering effect, messages may be put far out of context if their duration exceeds a certain threshold. If stock Toasts were modified so that they can display longer than LENGTH_LONG the message would linger on the screen until the application's process is terminated as toast views are added to the WindowManager and not a ViewGroup in your app. I would assume this is why it is hard coded.

If you absolutely need to show a toast style message longer than three and a half seconds I recommend building a view that gets attached to the Activity's content, that way it will disappear when the user exits the application. My SuperToasts library deals with this issue and many others, feel free to use it! You would most likely be interested in using SuperActivityToasts

Whitmer answered 23/6, 2013 at 19:38 Comment(0)
R
4

Simply use SuperToast to make an elegant toast on any situation. Make your toast colourful. Edit your font color and also it's size. Hope it will be all in one for you.

Roughcast answered 29/2, 2016 at 5:57 Comment(0)
T
4

Why eat Toast, when you can have the entire Snackbar: https://developer.android.com/reference/android/support/design/widget/Snackbar.html

Snackbar > Toast, Custom Toast, Crouton

Tarrah answered 18/3, 2016 at 1:25 Comment(0)
F
4

No, and most/all of the hacks listed here no longer work in android 9. But there's a much better solution: if you message needs to hang around, use a dialog box.

(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();
Fullerton answered 19/7, 2019 at 4:17 Comment(1)
Although this is not the answer Hussein was looking for, it's a better option than all those 'hacks'!Greet
S
2

The user cannot custome defined the Toast's duration. because NotificationManagerService's scheduleTimeoutLocked() function not use the field duration. the source code is the following.

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);
    }
Spradlin answered 18/11, 2013 at 8:44 Comment(0)
S
2

Use Crouton, it is a very flexible Toast library.

Crouton

You can use it just like toasts:

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

or you can even go a little deeper and customise it more, like setting the time to infinite! for example here I want to show a toast message until the user acknowledges it by clicking on it.

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

Custome Layout that will be inflated for the 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>
Starfish answered 11/9, 2014 at 4:23 Comment(0)
D
1

A toast with custom background and view did the trick for me. I tested it in nexus 7 tablet and I noticed no fadein fadeout animation during looping. Heres the implementation:

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

}

Heres the custom textview used in above code:

<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 is making my toast have rounded corner as in kitkat version. You can add other views too in the file. Any modifications for improvement and comments are encouraged as I am planning to implement this in my live app.

Dietetic answered 13/6, 2014 at 10:12 Comment(0)
S
1

Schedule a countdown until a time in the future, with regular notifications on intervals along the way. Example of showing a 30 second countdown in a text field:


     new CountDownTimer(30000, 1000) {

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

     public void onFinish() {
         mTextField.setText("done!");
     }
  }.start();


Seminole answered 31/12, 2016 at 17:17 Comment(0)
M
1

This text will disappear in 5 seconds.

    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: As Itai Spector in comment said it will be shown about 3.5 seconds, So use this 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();
Mclin answered 8/2, 2017 at 10:54 Comment(2)
I think this text will disappear after 3.5 secondsPopulate
@ItaiSpector: Check my new Code, Please.Mclin
U
1

Toast duration can be hacked using a thread that runs the toast exclusively. This works (runs the toast for 10 secs, modify sleep and ctr to your liking):

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();
Unrequited answered 26/4, 2018 at 15:51 Comment(0)
A
1

After failing with every available solution, I finally had workaround using recursion.

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);
}
Aspectual answered 19/6, 2018 at 20:13 Comment(1)
Most of the solutions on this question relating to calling "show" repeatedly to keep the toast displayed are doing so with the same toast instance, whereas yours is actually creating a new toast instance every second and specifying that each one should be shown for the LONG duration (normally 3.5 seconds). Not only is this inefficient because you keep creating extra object instances, but also Android puts toast messages into a queue to be shown one after another for their specified duration. So if you called this with a duration of 5, the message would actually show for 17.5 seconds.Sauterne
L
0

A very simple approach to creating a slightly longer message is as follows:

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

Note that the above example eliminates the LENGTH_SHORT option to keep the example simple.

You will generally not want to use a Toast message to display messages for very long intervals, as that is not the Toast class' intended purpose. But there are times when the amount of text you need to display could take the user longer than 3.5 seconds to read, and in that case a slight extension of time (e.g., to 6.5 seconds, as shown above) can, IMO, be useful and consistent with the intended usage.

Lowercase answered 9/12, 2011 at 1:35 Comment(0)
C
0
Toast.makeText(this, "Text", Toast.LENGTH_LONG).show(); 
Toast.makeText(this, "Text", Toast.LENGTH_LONG).show();

A very simple solution to the question. Twice or triple of them will make Toast last longer. It is the only way around.

Checkers answered 14/9, 2013 at 14:37 Comment(4)
Though sounds hack, but appreciate the thinking !Bewilderment
why downvoted a similar solution mentioned by @Alyss uses the same trick with the for loopVulcanology
This approach worked for me. It would be good to hear from those who down voted why they did so.Ib
this doesn't work any longer in android 9 and later.Fullerton
D
0

Sets toast to a specific period in milli-seconds:

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);
        }
    }
}
Diffract answered 26/8, 2015 at 9:34 Comment(0)
D
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();
      }
Defensible answered 26/3, 2018 at 21:30 Comment(0)
M
-1
val toast = Toast.makeText(this, "", Toast.LENGTH_LONG)

val countDownTimer = object : CountDownTimer(5000, 1000) {
    override fun onTick(millisUntilFinished: Long) { }
    override fun onFinish() { toast.cancel() }
}

toast.show()
countDownTimer.start()
Marje answered 16/9, 2021 at 21:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.