Adroid中Toast自定义显示时间

来源:互联网 发布:网络销售做外汇是什么 编辑:程序博客网 时间:2024/06/07 17:49

       Toast是Android中使用频率较高的弹窗提示手段,使用起来简单、方便。常规使用方法这里不做说明,继前一片博客《Android中Toast全屏显示》,其中抛砖引玉的给出一个简单的实现Toast全屏显示的方法后,发现无法控制Toast的显示时长。虽然Toast中有setDuration(int duration)接口,但是跟踪代码发现,设置的时间没起作用,只有系统默认的两个时间LENGTH_DURATION = 3500毫秒,SHORT_DURATION = 2000毫秒。也就是说,无论我们设置多长时间,最终影响Toast弹窗时间的只有Toast.LENGTH_LONG和Toast.LENGTH_SHORT两个参数。

       目前解决该问题的方法主要有两个:

1、利用反射原理,通过控制Toast的show()和hide()接口来控制显示时间,可参见博客《利用反射机制控制Toast的显示时间》。不过该方法只对Android4.0以下的系统有效,通过模拟器实测,也是如此。当前系统基本都在Android4.0以上,该方法过于老旧。

2、利用WindowManager的addView()方法动态刷屏,可看见博客《Android自定义Toast,可设定显示时间》。该方法被很多软件用来显示浮动窗口和图片的动态悬浮效果,如360手机软件和一些手游软件。在Android4.0上是一种不错的选择。当然,对于遇到系统默认把悬浮窗口功能关闭的手机,这招可能就不灵了。

       通过分析Toast的显示原理和弹窗控制逻辑,本人借助Handler和Runnable机制,也成功实现了对Toast显示任意自定义时长。代码是在Toast全屏显示的基础上修改而来,贴出如下:

package com.dls.nltest;import android.content.Context;import android.os.Handler;import android.util.DisplayMetrics;import android.util.Log;import android.view.Gravity;import android.view.WindowManager;import android.widget.LinearLayout;import android.widget.TextView;import android.widget.Toast;import android.widget.LinearLayout.LayoutParams;public class GenericToast{private static final String TAG = "GenericToast";private static final int TOAST_TEXTSIZE = 20;/** {@link Toast#LENGTH_SHORT} default time is 3500ms */private static final int LENGTH_SHORT_TIME = 2000;private static Context mContext = null;private static Toast mToast = null;private static TextView mTextView = null;private static int mDuration = 0;private static CharSequence mText = null;private Handler mHandler = new Handler();private GenericToast(Context context) {mContext = context;}public static GenericToast makeText(Context context, CharSequence text, int duration){GenericToast instance = new GenericToast(context);mContext = context;mDuration = duration;mText = text;return instance;}private static void getToast(Context context, CharSequence text){mToast = Toast.makeText(context, null, Toast.LENGTH_LONG);mToast.setGravity(Gravity.CENTER, 0, 0);LinearLayout toastView = (LinearLayout)mToast.getView();// Get the screen size with unit pixels.WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);DisplayMetrics outMetrics = new DisplayMetrics();wm.getDefaultDisplay().getMetrics(outMetrics);mTextView = new TextView(context);LayoutParams vlp = new LayoutParams(outMetrics.widthPixels,                            outMetrics.heightPixels);vlp.setMargins(0, 0, 0, 0);mTextView.setLayoutParams(vlp);mTextView.setTextSize(TOAST_TEXTSIZE);mTextView.setText(text);mTextView.setGravity(Gravity.CENTER);toastView.addView(mTextView);}/** * Before call this method, you should call {@link makeText}. * * @return Toast display duration. */public int getDuration(){return mDuration;}public void show(){Log.d(TAG, "Show custom toast");mHandler.post(showRunnable);}public void hide(){Log.d(TAG, "Hide custom toast");mDuration = 0;if(mToast != null){mToast.cancel();}}private Runnable showRunnable = new Runnable(){@Overridepublic void run() {if(mToast != null){mTextView.setText(mText);}else{getToast(mContext, mText);}if(mDuration != 0){mToast.show();}else{Log.d(TAG, "Hide custom toast in runnable");hide();return;}if(mDuration > LENGTH_SHORT_TIME){mHandler.postDelayed(showRunnable, LENGTH_SHORT_TIME);mDuration -= LENGTH_SHORT_TIME;}else{mHandler.postDelayed(showRunnable, mDuration);mDuration = 0;}}};}
Toast弹窗10s,测试代码如下:

GenericToast mGToast = GenericToast.makeText(this, "I am generic toast", 10 * 1000);mGToast.show();
如果需要终止弹窗,只要在需要的地方调用hide()即可。

0 0
原创粉丝点击