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


当前回答

如果你想要一个Toast持续存在,我发现你可以通过让一个Timer反复调用Toast .show()来解决它(每秒钟左右应该这样做)。如果Toast已经显示,调用show()不会中断任何内容,但是它会刷新Toast在屏幕上停留的时间。

其他回答

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

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秒)可能是有用的,并且与预期的用法一致。

使用Crouton,这是一个非常灵活的吐司库。

油煎面包块

你可以像烤面包一样使用它:

Crouton.makeText(context, "YOUR_MESSAGE", Style.INFO);

或者你甚至可以更深入一点,自定义更多,比如将时间设置为无限!例如,在这里我想显示一个toast消息,直到用户通过点击它来确认它。

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

如果你深入挖掘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

我知道答案已经很晚了。我也有同样的问题,在研究了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);

}

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