Android Toast自定义显示时间
Toast是Android中使用频率较高的弹窗提示手段,使用起来简单、方便。常规使用方法这里不做说明,继前一篇博客《Android中Toast全屏显示》,其中抛砖引玉的给出一个简单的实现Toast全屏显示的方法后,发现无法控制Toast的显示时长。虽然Toast中有setDuration(intduration)接口,但是跟踪代码发现,设置的时间没起作用,只有系统默认的两个时间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全屏显示的基础上修改而来,贴出如下:
packagecom.dls.nltest;
importandroid.content.Context;
importandroid.os.Handler;
importandroid.util.DisplayMetrics;
importandroid.util.Log;
importandroid.view.Gravity;
importandroid.view.WindowManager;
importandroid.widget.LinearLayout;
importandroid.widget.TextView;
importandroid.widget.Toast;
importandroid.widget.LinearLayout.LayoutParams;
publicclassGenericToast{
privatestaticfinalStringTAG="GenericToast";
privatestaticfinalintTOAST_TEXTSIZE=20;
/**{@linkToast#LENGTH_SHORT}defaulttimeis3500ms*/
privatestaticfinalintLENGTH_SHORT_TIME=2000;
privatestaticContextmContext=null;
privatestaticToastmToast=null;
privatestaticTextViewmTextView=null;
privatestaticintmDuration=0;
privatestaticCharSequencemText=null;
privateHandlermHandler=newHandler();
privateGenericToast(Contextcontext){
mContext=context;
}
publicstaticGenericToastmakeText(Contextcontext,CharSequencetext,intduration){
GenericToastinstance=newGenericToast(context);
mContext=context;
mDuration=duration;
mText=text;
returninstance;
}
privatestaticvoidgetToast(Contextcontext,CharSequencetext){
mToast=Toast.makeText(context,null,Toast.LENGTH_LONG);
mToast.setGravity(Gravity.CENTER,0,0);
LinearLayouttoastView=(LinearLayout)mToast.getView();
//Getthescreensizewithunitpixels.
WindowManagerwm=(WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetricsoutMetrics=newDisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
mTextView=newTextView(context);
LayoutParamsvlp=newLayoutParams(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);
}
/**
*Beforecallthismethod,youshouldcall{@linkmakeText}.
*
*@returnToastdisplayduration.
*/
publicintgetDuration(){
returnmDuration;
}
publicvoidshow(){
Log.d(TAG,"Showcustomtoast");
mHandler.post(showRunnable);
}
publicvoidhide(){
Log.d(TAG,"Hidecustomtoast");
mDuration=0;
if(mToast!=null){
mToast.cancel();
}
}
privateRunnableshowRunnable=newRunnable(){
@Override
publicvoidrun(){
if(mToast!=null){
mTextView.setText(mText);
}else{
getToast(mContext,mText);
}
if(mDuration!=0){
mToast.show();
}else{
Log.d(TAG,"Hidecustomtoastinrunnable");
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,测试代码如下:
GenericToastmGToast=GenericToast.makeText(this,"Iamgenerictoast",10*1000); mGToast.show();
如果需要终止弹窗,只要在需要的地方调用hide()即可。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。