当为Toast使用setDuration()时,是否可以设置一个自定义长度或至少比Toast. length_long更长的长度?


当前回答

下面是我用上面的代码创建的一个自定义Toast类:

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

其他回答

我知道答案已经很晚了。我也有同样的问题,在研究了android的Toast源代码后,决定实现我自己的裸骨吐司版本。

基本上,您需要创建一个新的窗口管理器,并使用处理程序在所需的持续时间内显示和隐藏窗口

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

初始化布局后,您可以使用自己的隐藏和显示方法

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

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

现在你所需要的就是添加两个可运行的线程,分别调用handleShow()和handleHide(),你可以将它们发布到Handler中。

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

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

最后一部分

public void show() {

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

}

这是一个快速而肮脏的实现。没有考虑到任何业绩。

LONG_DELAY吐司显示为3.5秒,SHORT_DELAY吐司显示为2秒。

Toast内部使用INotificationManager并在每次调用Toast.show()时调用它的enqueueToast方法。

使用SHORT_DELAY调用show()两次将再次将同一toast排队。它将显示4秒(2秒+ 2秒)。

类似地,两次使用LONG_DELAY调用show()将再次将同一toast排队。它将显示7秒(3.5秒+ 3.5秒)

计划一个倒计时,直到将来的某个时间,并在此过程中定期通知。在文本框中显示30秒倒计时的例子:


     new CountDownTimer(30000, 1000) {

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

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


你可能想试试:

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

使时间加倍。如果你指定3而不是2,它会使时间增加三倍等等。

如果你深入挖掘android代码,你会发现这些行清楚地表明,我们不能改变Toast消息的持续时间。

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

持续时间的默认值为

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