Android Toast可以比Toast.LENGTH_LONG长吗?
当使用setDuration()作为Toast时,是否可以设置一个自定义的长度,或者至less比Toast.LENGTH_LONG
长一些?
LENGTH_SHORT
和LENGTH_LONG
的值是0和1.这意味着它们被视为标志而不是实际持续时间,所以我不认为可以将持续时间设置为除这些值之外的任何值。
如果要向用户显示更长的消息,请考虑状态栏通知 。 状态栏通知在不再相关时可以通过程序取消。
如果你深入了解android代码,你可以find明确指出的行,我们不能改变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(); }
把时间加倍 如果你指定3,而不是2它将三倍的时间..等等。
避免按顺序推出的敬酒之间的褪色效果的最佳解决scheme:
final Toast tag = Toast.makeText(getBaseContext(), "YOUR MESSAGE",Toast.LENGTH_SHORT); tag.show(); new CountDownTimer(9000, 1000) { public void onTick(long millisUntilFinished) {tag.show();} public void onFinish() {tag.show();} }.start();
在这里,烤面包约显示10秒。
希望这可以帮助。
如果你想要Toast
坚持下去,我发现你可以通过反复调用toast.show()
(每隔toast.show()
调用toast.show()
来解决这个问题。 如果Toast
已经显示,则调用show()
不会中断任何事情,但会刷新屏幕上停留的时间。
我已经编写了一个辅助类来做这件事。 你可以在github上看到代码: https : //github.com/quiqueqs/Toast-Expander/blob/master/src/com/thirtymatches/toasted/ToastedActivity.java
这是你如何显示烤面包5秒(或5000毫秒):
Toast aToast = Toast.makeText(this, "Hello World", Toast.LENGTH_SHORT); ToastExpander.showFor(aToast, 5000);
我已经开发了一个自定义吐司类,你可以显示吐司所需的持续时间(以毫秒为单位)
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); } } }
我知道我有点晚了,但我采取了Regis_AG的答案,并将其包装在助手类中,它的效果很好。
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);
我知道答案是相当晚的..我有同样的问题,并决定实施自己的版本的裸骨吐司,看着Android的源代码吐司。
基本上你需要创build一个新的窗口pipe理器,并使用处理程序显示和隐藏所需持续时间的窗口
//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); }
这是一个快速和肮脏的实施..没有考虑到任何performance。
LONG_DELAY吐司显示3.5秒 , SHORT_DELAY吐司显示2秒 。
Toast内部使用INotificationManager,每次调用Toast.show()时调用它的enqueueToast方法。
用SHORT_DELAY调用show()两次将重新排列相同的Toast。 它会显示4秒 (2秒+ 2秒)。
同样,用LONG_DELAY调用show()两次将重新排列相同的敬酒。 它将显示7秒 (3.5秒+ 3.5秒)
这是我使用上面的代码所做的自定义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(); } }
如果你需要一个很长的吐司,这里有一个实用的select,但它需要你的用户点击确定button,使其消失。 你可以像这样使用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();
如果你有一个很长的信息,很可能你不知道用户阅读邮件需要多长时间,所以有时候要求你的用户点击一个OKbutton来继续是一个好主意。 在我的情况下,当用户点击帮助图标时,我使用这种技术。
正如其他人所提到的Android Toast可以是LENGTH_LONG或LENGTH_SHORT。 这是没有办法的,也不应该遵循任何“黑客”张贴。
敬酒的目的是显示“非必要”的信息,由于其持久的效果,如果信息的持续时间超过一定的阈值,信息可能会被置于远离语境的地步。 如果股票Toast被修改,以便它们可以显示比LENGTH_LONG更长的时间,则消息将在屏幕上逗留直到应用程序的进程终止,因为Toast视图被添加到WindowManager而不是您的应用中的ViewGroup。 我会认为这就是为什么它是硬编码。
如果你绝对需要显示一个超过三秒半的吐司风格的消息,我build议build立一个附加到活动内容的视图,这样当用户退出应用程序时,它将消失。 我的SuperToast图书馆处理这个问题和许多其他人,随时使用它! 你很可能有兴趣使用SuperActivityToasts
只要使用SuperToast在任何情况下做一个优雅的吐司。 让你的吐司丰富多彩 。 编辑您的字体颜色 ,也是它的大小 。 希望这将是一个一个给你。
用户不能自定义Toast的持续时间。 因为NotificationManagerService的scheduleTimeoutLocked()函数不使用字段持续时间。 源代码如下。
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); }
使用油煎面包,这是一个非常灵活的吐司图书馆。
Crouton
你可以像吐司一样使用它:
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>
为什么要吃吐司,当你可以有整个小吃店 : https : //developer.android.com/reference/android/support/design/widget/Snackbar.html
小吃店>吐司,定制烤面包,面包
自定义背景和视图烤面包为我做了伎俩。 我testing了nexus 7平板电脑,我发现循环期间没有淡入淡出的animation。 inheritance人:
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:
<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正在让我的烤面包拥有圆angular,就像kitkat版本一样。 您也可以在文件中添加其他视图。 鼓励任何对改进和评论的修改,因为我打算在我的实时应用程序中实现这一点。
这是一个非常简单的方法,为我工作:
for (int i=0; i < 3; i++) { Toast.makeText(this, "MESSAGE", Toast.LENGTH_SHORT).show(); }
LENGTH_SHORT的持续时间是2秒,LENGTH_LONG是3.5秒,这里Toast消息将被显示6秒,因为它被封闭在for循环中。 但是这种方法的一个缺点是在每2秒后会出现一个小的衰落效应。 但不是很明显。 希望这是有帮助的
安排一个倒计时,直到将来的一段时间,定期通知一段时间。 在文本字段中显示30秒倒数的示例:
新的CountDownTimer(30000,1000){ public void onTick(long millisUntilFinished){ mTextField.setText(“seconds remaining:”+ millisUntilFinished / 1000); } public void onFinish(){ mTextField.setText( “完成了!”); } }。开始();
这段文字将在5秒内消失。
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
创build稍长的消息的一个非常简单的方法如下:
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秒),IMO可能有用并符合预期用途。
以毫秒为单位设置特定的时间段:
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); } } }
Toast.makeText(this, "Text", Toast.LENGTH_LONG).show(); Toast.makeText(this, "Text", Toast.LENGTH_LONG).show();
问题的一个非常简单的解决scheme。 他们两次或三次会使吐司持续更长的时间。 这是唯一的方法。
您可以在Toast.makeText();
以毫秒为单位设置所需的时间Toast.makeText();
像这样的方法:
//40 seconds long mToastLength = 40*1000 //this toast will be displayed for 40 seconds. Toast.makeText(this, "Hello!!!!!", mToastLength).show();