Can an Android Toast be longer than Toast.LENGTH_LONG?

Viewed 216239

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

27 Answers

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.

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.

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

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

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

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