@linux1s1s
2017-01-22T16:52:03.000000Z
字数 4439
阅读 8141
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() {
@Override
public 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;
@Override
public 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() {
@Override
public 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);
}
}