251 android android-toast
当使用setDuration()进行Toast时,是否可以设置自定义长度或至少长于Toast.LENGTH_LONG?
Fee*_*ood 329
如果你深入挖掘android代码,你可以找到明确指出的行,我们不能改变Toast消息的持续时间.
NotificationManagerService.scheduleTimeoutLocked() {
...
long delay = immediate ? 0 : (r.duration == Toast.LENGTH_LONG ? LONG_DELAY : SHORT_DELAY);
}
Run Code Online (Sandbox Code Playgroud)
和持续时间的默认值是
private static final int LONG_DELAY = 3500; // 3.5 seconds
private static final int SHORT_DELAY = 2000; // 2 seconds
Run Code Online (Sandbox Code Playgroud)
Dav*_*ebb 135
的价值观LENGTH_SHORT和LENGTH_LONG是0和1.这意味着它们是作为标志,而不是实际的持续时间处理,所以我不认为这将有可能设置持续时间比这些数值的任何其他.
如果要向用户显示更长时间的消息,请考虑状态栏通知.状态栏通知可以在不再相关时以编程方式取消.
小智 119
你可能想尝试:
for (int i=0; i < 2; i++)
{
Toast.makeText(this, "blah", Toast.LENGTH_LONG).show();
}
Run Code Online (Sandbox Code Playgroud)
加倍的时间.如果你指定3而不是2它将使时间增加三倍.等等.
Reg*_*_AG 98
避免按顺序启动的祝酒之间的褪色效果的最佳解决方案:
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();
Run Code Online (Sandbox Code Playgroud)
这里吐司显示大约10秒.
希望这可以帮助.
ian*_*sme 32
如果你想要Toast坚持下去,我发现你可以通过反复Timer拨打电话来破解你的方式toast.show()(每隔一秒左右应该这样做).show()如果Toast已经显示,则调用不会破坏任何内容,但它会刷新它在屏幕上停留的时间.
Gop*_*opi 17
我开发了一个自定义Toast类,您可以使用它来显示Toast所需的持续时间(毫秒)
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
Hen*_*que 13
我编写了一个辅助类来执行此操作.您可以在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);
Run Code Online (Sandbox Code Playgroud)
Chr*_*son 10
我知道我有点晚了,但是我把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();
}
}
Run Code Online (Sandbox Code Playgroud)
在您的应用程序代码中,只需执行以下操作:
Toaster.makeLongToast("Toasty!", 8000);
Run Code Online (Sandbox Code Playgroud)
我知道答案已经很晚了.我遇到了同样的问题并决定在查看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;
Run Code Online (Sandbox Code Playgroud)
初始化布局后,您可以使用自己的隐藏和显示方法
public void handleShow() {
mWindowManager.addView(mLayout, mParams);
}
public void handleHide() {
if (mLayout != null) {
if (mLayout.getParent() != null) {
mWindowManager.removeView(mLayout);
}
mLayout = null;
}
Run Code Online (Sandbox Code Playgroud)
现在你只需要添加两个可运行的线程来调用handleShow()和handleHide(),你可以将它们发送给Handler.
Runnable toastShowRunnable = new Runnable() {
public void run() {
handleShow();
}
};
Runnable toastHideRunnable = new Runnable() {
public void run() {
handleHide();
}
};
Run Code Online (Sandbox Code Playgroud)
最后一部分
public void show() {
mHandler.post(toastShowRunnable);
//The duration that you want
mHandler.postDelayed(toastHideRunnable, mDuration);
}
Run Code Online (Sandbox Code Playgroud)
这是一个快速而肮脏的实现..没有考虑任何性能.
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秒)
这是我使用上面的代码制作的自定义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();
}
}
Run Code Online (Sandbox Code Playgroud)
正如其他人所提到的,Android Toasts可以是LENGTH_LONG或LENGTH_SHORT.没有办法解决这个问题,也不应该遵循发布的任何"黑客".
Toasts的目的是显示"非必要"信息,并且由于它们的延迟效应,如果消息的持续时间超过某个阈值,则消息可能远远超出上下文.如果库存Toasts被修改以便它们显示的时间长于LENGTH_LONG,则消息将在屏幕上停留,直到应用程序的进程终止,因为Toast视图被添加到WindowManager而不是应用程序中的ViewGroup.我认为这就是硬编码的原因.
如果您绝对需要显示超过三秒半的Toast样式消息,我建议构建一个附加到Activity内容的视图,这样当用户退出应用程序时它将消失.我的SuperToasts库处理这个问题和许多其他人,随时使用它!您很可能对使用SuperActivityToasts感兴趣
如果你需要一个很长的Toast,有一个实用的替代方案,但它需要你的用户单击一个OK按钮让它消失.你可以像这样使用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();
Run Code Online (Sandbox Code Playgroud)
如果您有一条很长的消息,很可能,您不知道您的用户需要多长时间才能阅读该消息,因此有时最好要求您的用户单击"确定"按钮继续.就我而言,当用户点击帮助图标时,我会使用此技术.
| 归档时间: |
|
| 查看次数: |
170108 次 |
| 最近记录: |