@linux1s1s
2017-01-22T08:52:03.000000Z
字数 4439
阅读 8501
AndroidWidget 2015-10
该方法直接通过Toast API,只是加了一步操作:检测显示的时间,超过这个时间直接cancel即可。
自定义的Toast View
@SuppressLint("InflateParams")public static View createToastLayout(CharSequence str, Context a, boolean supportTextType) {View pgLayout = supportTextType ? LayoutInflater.from(a).inflate(R.layout.xxxx, null) : LayoutInflater.from(a).inflate(R.layout.xxxxxx_hint, null);TangFontTextView tv = (TangFontTextView) pgLayout.findViewById(R.id.toast_textview);if(!TextUtils.isEmpty(str)){tv.setText(str);}return pgLayout;}
Toast初始化。
public static Toast createToast(CharSequence str, Context a, boolean supportTextType){View pgLayout = createToastLayout(str, a, supportTextType);Toast toast = new Toast(a);toast.setView(pgLayout);toast.setDuration(Toast.LENGTH_LONG);toast.setGravity(Gravity.CENTER, 0, 0);return toast;}
Toast显示和检测时间
public void showRemoveRemindTips(final BaseSherlockActivity activity, final String tips){final Toast toast = CustomToast.createToast(tips, activity, false);toast.show();mHandler.postDelayed(new Runnable() {@Overridepublic void run() {toast.cancel();}}, 1500);}
该方法来自网络-Android中通过反射来设置Toast的显示时间,并部分修改,特此说明。
这个方法是网上通用的方法,适合显示时间任意自定义的情况,具体的思路如下:
首先借助TN类,所有的显示逻辑在这个类中的show方法中,然后再实例一个TN类变量,将传递到一个队列中进行显示,所以我们要向解决这个显示的时间问题,那就从入队列这部给截断,因为一旦toast入队列了,我们就控制不了,因为这个队列是系统维护的,所以我们现在的解决思路是:
1、不让toast入队列
2、然后我们自己调用TN类中的show和hide方法
第一个简单,我们不调用toast方法就可以了,但是第二个有点问题了,因为我们看到TN这个类是私有的,所以我们也不能实例化他的对象,但是toast类中有一个实例化对象:tn
final TN mTN;
该成员变量是包访问权限,所以需要借助反射,我们只需要反射出这个变量就可以得到这个TN类对象了,然后再使用反射获取他的show和hide方法即可,下面我们就来看一下实际的代码吧:
package com.weijia.toast;import java.lang.reflect.Field;import java.lang.reflect.Method;import android.content.Context;import android.view.View;import android.widget.Toast;public class ReflectToast {Context mContext;private Toast mToast;private Field field;private Object obj;private Method showMethod, hideMethod;public ReflectToast(Context c, View v) {this.mContext = c;mToast = new Toast(mContext);mToast.setView(v);reflectionTN();}public void show() {try {showMethod.invoke(obj, null);} catch (Exception e) {e.printStackTrace();}}public void cancel() {try {hideMethod.invoke(obj, null);} catch (Exception e) {e.printStackTrace();}}private void reflectionTN() {try {field = mToast.getClass().getDeclaredField("mTN");field.setAccessible(true);//强暴obj = field.get(mToast);showMethod = obj.getClass().getDeclaredMethod("show", null);hideMethod = obj.getClass().getDeclaredMethod("hide", null);} catch (Exception e) {e.printStackTrace();}}}
这里我们实例化一个Toast对象,但是没有调用showf方法,就是不让toast入系统显示队列中,这样就可以控制show方法和hide方法的执行了,下面是测试代码:
package com.weijia.toast;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.TextView;public class MainActivity extends Activity {ReflectToast toast;boolean isShown = false;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);final TextView tView = new TextView(this);tView.setText("ReflectToast !!!");toast = new ReflectToast(this, tView);findViewById(R.id.show_toast).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if(isShown){toast.cancel();isShown = false;}else{toast.show();isShown = true;}}});}}
注意:这里有一个问题,我开始的时候用三星手机测试的,没有任何效果,然后换成小米手机也不行,最后用模拟器测试是可以的了。具体原因还在解决中。。。
该方法来自网络-Android进阶篇-Toast自定义显示时间,不说废话,直接上干货。
public class CustomToast {public static final int LENGTH_MAX = -1;private boolean mCanceled = true;private Handler mHandler;private Context mContext;private Toast mToast;public CustomToast(Context context) {this(context,new Handler());}public CustomToast(Context context,Handler h) {mContext = context;mHandler = h;mToast = Toast.makeText(mContext,"",Toast.LENGTH_SHORT);mToast.setGravity(Gravity.BOTTOM, 0, 0);}public void show(int resId,int duration) {mToast.setText(resId);if(duration != LENGTH_MAX) {mToast.setDuration(duration);mToast.show();} else if(mCanceled) {mToast.setDuration(Toast.LENGTH_LONG);mCanceled = false;showUntilCancel();}}/*** @param text 要显示的内容* @param duration 显示的时间长* 根据LENGTH_MAX进行判断* 如果不匹配,进行系统显示* 如果匹配,永久显示,直到调用hide()*/public void show(String text,int duration) {mToast.setText(text);if(duration != LENGTH_MAX) {mToast.setDuration(duration);mToast.show();} else {if(mCanceled) {mToast.setDuration(Toast.LENGTH_LONG);mCanceled = false;showUntilCancel();}}}/*** 隐藏Toast*/public void hide(){mToast.cancel();mCanceled = true;}public boolean isShowing() {return !mCanceled;}private void showUntilCancel() {if(mCanceled)return;mToast.show();mHandler.postDelayed(new Runnable() {public void run() {showUntilCancel();}},3000);}}
