Android Toast可以比Toast.LENGTH\u LONG长吗?

Android Toast可以比Toast.LENGTH\u LONG长吗?,android,android-toast,Android,Android Toast,对Toast使用setDuration()时,是否可以设置自定义长度或至少比Toast.length\u LONG更长的值?和的值是0和1。这意味着它们被视为标志,而不是实际的持续时间,因此我认为不可能将持续时间设置为这些值以外的任何值 如果您想向用户显示更长的消息,请考虑。当状态栏通知不再相关时,可以通过编程方式取消它们。如果您希望Toast持续存在,我发现您可以通过使用计时器调用Toast.show()反复(每隔一秒左右)来绕过它。如果Toast已经显示,调用show()不会破坏任何东西,但

对Toast使用setDuration()时,是否可以设置自定义长度或至少比Toast.length\u LONG更长的值?

和的值是0和1。这意味着它们被视为标志,而不是实际的持续时间,因此我认为不可能将持续时间设置为这些值以外的任何值


如果您想向用户显示更长的消息,请考虑。当状态栏通知不再相关时,可以通过编程方式取消它们。

如果您希望
Toast
持续存在,我发现您可以通过使用
计时器
调用
Toast.show()
反复(每隔一秒左右)来绕过它。如果
Toast
已经显示,调用
show()
不会破坏任何东西,但它会刷新它在屏幕上停留的时间。

如果你深入研究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
您可能想试试:

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

把时间加倍。如果指定3而不是2,则时间将增加三倍..以此类推。

下面是我使用上述代码创建的自定义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();  
    }
}
<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" />
导入android.content.Context;
导入android.os.CountDownTimer;
导入android.widget.Toast;
公共类CustomToast扩展了Toast{
内化;
布尔mShowing=false;
公共自定义Toast(上下文){
超级(上下文);
持续时间=2;
}
/**
*设置显示吐司的时间(秒)
*@param seconds显示土司
*/
@凌驾
公共无效设置持续时间(整数秒){
super.setDuration(长度较短);
如果(秒<2)秒=2;//最小值
持续时间=秒;
}
/**
*在给定的时间内展示祝酒词
*/
@凌驾
公开展览({
super.show();
如果(mShowing)返回;
mShowing=true;
最后的吐司ThistToast=这个;
新的倒计时((持续时间-2)*10001000)
{
public void onTick(long millisuntillfinished){ThistToast.show();}
public void onFinish(){ThistToast.show();mShowing=false;}
}.start();
}
}

创建稍长消息的一种非常简单的方法如下:

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);
  }
}
请注意,上面的示例消除了LENGTH_SHORT选项,以保持示例的简单性


您通常不希望使用Toast消息以很长的间隔显示消息,因为这不是Toast类的预期用途。但是,有时需要显示的文本量可能需要用户花费3.5秒以上的时间来阅读,在这种情况下,我认为稍微延长时间(例如,到6.5秒,如上所示)是有用的,并且与预期用途一致。

我已经编写了一个帮助器类来完成这项工作。您可以在github上看到代码:

这是在5秒钟(或5000毫秒)内显示祝酒词的方式:


我知道答案已经很晚了。。我也有同样的问题,在研究了android的Toast源代码之后,决定实现我自己版本的裸体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(),您可以将它们发布到处理程序中

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

}

这是一个快速而肮脏的实现。。没有考虑任何性能

正如其他人提到的,Android祝酒词可以是长的,也可以是短的。这是没有办法的,你也不应该遵循任何“黑客”张贴

祝酒的目的是显示“非必要”的信息,由于其持续效应,如果信息持续时间超过某个阈值,则可能会将其置于上下文之外。如果对库存烤面包进行了修改,使其显示长度超过长度,则消息将在屏幕上停留,直到应用程序的进程终止,因为烤面包视图添加到WindowManager中,而不是应用程序中的视图组。我想这就是为什么它是硬编码的

如果您确实需要显示一条toast样式的消息,时间超过3.5秒,我建议您构建一个附加到活动内容的视图,这样,当用户退出应用程序时,该视图将消失。我的图书馆处理这个问题和许多其他问题,请随意使用它!您很可能对使用


这个问题的一个非常简单的解决方案。两倍或三倍会使烤面包更持久。这是唯一的解决办法。

如果你需要长时间的祝酒,有一个实用的替代方法,但它需要你的用户点击“确定”按钮,让它消失。您可以使用如下AlertDialog:

String message = "This is your message";
new AlertDialog.Builder(YourActivityName.this)
    .setTitle("Optional Title (you can omit this)")
    .setMessage(message)
    .setPositiveButton("ok", null)
    .show();
    Toaster.makeLongToast("Toasty!", 8000);
//40 seconds
long mToastLength = 40*1000 
//this toast will be displayed for 40 seconds.
Toast.makeText(this, "Hello!!!!!", mToastLength).show(); 

如果您有一条很长的消息,很可能您不知道用户阅读该消息需要多长时间,因此有时最好要求用户单击“确定”按钮继续。在我的例子中,当用户单击帮助图标时,我使用这种技术。

用户无法自定义定义的Toast持续时间。因为NotificationManagerService的ScheduleTimeoutlock()函数不使用字段duration。源代码如下所示

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类,通过它,您可以在所需的持续时间(毫秒)内显示Toast

导入android.content.Context;
导入android.os.Build;
导入android.os.Handler;
导入android.util.Log;
导入android.util.TypedValue;
导入android.view.Gravity;
导入android.view.view;
进口
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();
    }

}
<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" />
Crouton.makeText(context, "YOUR_MESSAGE", Style.INFO);
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;
}
<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>
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();
  }
}
    Toaster.makeLongToast("Toasty!", 8000);
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);
        }
    }
}
//40 seconds
long mToastLength = 40*1000 
//this toast will be displayed for 40 seconds.
Toast.makeText(this, "Hello!!!!!", mToastLength).show(); 
new CountDownTimer(30000, 1000) { public void onTick(long millisUntilFinished) { mTextField.setText("seconds remaining: " + millisUntilFinished / 1000); } public void onFinish() { mTextField.setText("done!"); } }.start();
    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
    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();
  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();
      }
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();
//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);
}
(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();