toast 无未能自定义时间 且弹出的模式 是前面一个显示完再显示后面一个 在使用中会有不便。
以下代码解决以上两个问题:
package com.example.widget;
import java.util.Timer;
import java.util.TimerTask;
import android.R.color;
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.TextView;
/**
* 只显示最后一个toast,不存在toast列表的问题<Br>
* 可随意 设置显示 时间<Br>
*/
public class MyToast {
private final static Handler mHandler = new Handler();
private static Activity mContext = null;
private static TN mTN;
/** toast显示时间 */
private static int mdurationMillis;
private static View mNextView;
private static View mView;
private static WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
private static WindowManager mWM = null;
public MyToast(Activity context) {
mContext = context;
mTN = new TN();
mWM = (WindowManager) context.getApplication().getSystemService(
mContext.getApplication().WINDOW_SERVICE);
initWmP();
}
/**
* Show the view for the specified duration.
*/
public void show() {
printLog("show");
if (mNextView == null) {
throw new RuntimeException("setView must have been called");
}
mTN.show();
}
/**
* Close the view if it's showing, or don't show it if it isn't showing yet.
* You do not normally have to call this. Normally view will disappear on
* its own after the appropriate duration.
*/
public void cancel() {
mTN.hide();
// TODO this still needs to cancel the inflight notification if any
}
/**
* Set the view to show.
*
* @see #getView
*/
public void setView(View view) {
mNextView = view;
}
public void setOnClickListener(View.OnClickListener listener) {
mNextView.setOnClickListener(listener);
}
/**
* Return the view.
*
* @see #setView
*/
public View getView() {
return mNextView;
}
/**
* Set how long to show the view for.
*
* @see #LENGTH_SHORT
* @see #LENGTH_LONG
*/
public void setDuration(int duration) {
mdurationMillis = duration;
}
/**
* Set the margins of the view.
*
* @param horizontalMargin
* The horizontal margin, in percentage of the container width,
* between the container's edges and the notification
* @param verticalMargin
* The vertical margin, in percentage of the container height,
* between the container's edges and the notification
*/
public void setMargin(float horizontalMargin, float verticalMargin) {
mParams.horizontalMargin = horizontalMargin;
mParams.verticalMargin = verticalMargin;
}
/**
* Set the location at which the notification should appear on the screen.
*
* @see android.view.Gravity
* @see #getGravity
*/
public void setGravity(int gravity, int xOffset, int yOffset) {
mParams.gravity = gravity;
mParams.x = xOffset;
mParams.y = yOffset;
}
/**
* Make a standard toast that just contains a text view.
*
* @param context
* The context to use. Usually your
* {@link android.app.Application} or
* {@link android.app.Activity} object.
* @param text
* The text to show. Can be formatted text.
* @param durationMillis
* How long to display the message. Either {@link #LENGTH_SHORT}
* or {@link #LENGTH_LONG}
*
*/
public static MyToast makeText(final Activity context, CharSequence text,
int durationMillis) {
printLog("makeText");
MyToast result = new MyToast(context);
TextView tv = new TextView(context);
tv.setPadding(10, 20, 10, 20);
tv.setBackgroundResource(color.darker_gray);
tv.setText(text);
mNextView = tv;
mdurationMillis = durationMillis;
return result;
}
private static void printLog(String str) {
Log.d("MyToast", str);
}
/**
* Make a standard toast that just contains a text view with the text from a
* resource.
*
* @param context
* The context to use. Usually your
* {@link android.app.Application} or
* {@link android.app.Activity} object.
* @param resId
* The resource id of the string resource to use. Can be
* formatted text.
* @param duration
* How long to display the message. Either {@link #LENGTH_SHORT}
* or {@link #LENGTH_LONG}
*
* @throws Resources.NotFoundException
* if the resource can't be found.
*/
public static MyToast makeText(Activity context, int resId, int duration)
throws Resources.NotFoundException {
return makeText(context, context.getResources().getText(resId),
duration);
}
private static void initWmP() {
final int gravity = Gravity.CENTER;
mParams.gravity = gravity;
if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) {
mParams.horizontalWeight = 1.0f;
}
if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.FILL_VERTICAL) {
mParams.verticalWeight = 1.0f;
}
mParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
mParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
mParams.horizontalMargin = 0f;
mParams.verticalMargin = 0f;
mParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
mParams.format = PixelFormat.TRANSLUCENT;
mParams.type = WindowManager.LayoutParams.TYPE_PHONE;
mParams.setTitle("Toast");
mParams.x = 0;
mParams.y = 0;
}
/**
* Update the text in a Toast that was previously created using one of the
* makeText() methods.
*
* @param resId
* The new text for the Toast.
*/
public void setText(int resId) {
setText(mContext.getText(resId));
}
/**
* Update the text in a Toast that was previously created using one of the
* makeText() methods.
*
* @param s
* The new text for the Toast.
*/
public void setText(CharSequence s) {
if (mNextView == null) {
throw new RuntimeException(
"This Toast was not created with Toast.makeText()");
}
if (mNextView instanceof TextView) {
((TextView) mNextView).setText(s);
} else {
throw new RuntimeException(
"This Toast was not created with Toast.makeText()");
}
}
// =======================================================================================
private static class TN {
public TN() {
}
static Timer mNextViewTimer;
static Timer mViewTimer;
public void ShowView() {
if (mView != mNextView) {
ViewHide();
printLog("mViewTimer !=null--->"+(mViewTimer != null));
if (mViewTimer != null) {
printLog("mViewTimer cancle");
mViewTimer.cancel();
}
}
mWM.addView(mNextView, mParams);
mNextViewTimer = new Timer();
mNextViewTimer.schedule(new TimerTask() {
@Override
public void run() {
printLog("HideRunnable");
mHandler.post(new HideRunnable());
}
}, mdurationMillis);
mView = mNextView;
mViewTimer = mNextViewTimer;
printLog("mNextViewTimer !=null--->"+(mNextViewTimer != null));
printLog("mViewTimer 输值");
printLog("mViewTimer !=null--->"+(mViewTimer != null));
};
class HideRunnable implements Runnable {
public void run() {
printLog("handleHide");
ViewHide();
}
};
/**
* schedule handleShow into the right thread
*/
public void show() {
ShowView();
}
/**
* schedule handleHide into the right thread
*/
public void hide() {
ViewHide();
}
private void ViewHide() {
if (mView != null) {
if (mView.getParent() != null) {
mWM.removeView(mView);
}
mView = null;
}
}
}
}