有时我们需要一个提示框,但这个提示框还不能获取焦点(比如视频播放,不能让提示框获取后面控制面板的焦点),但是,如一直快进android的提示框Toast又不能定时退出,或者显示时间不理想;网上看了许多例子,有用定时器handler来控制定时显示的,继承Toast方法写的,都不是太理想;这里我们用反射加部分重写,来实现它:
1,CustomToast.java
public class CustomToast extends Toast {
private boolean isShowing = false;
public CustomToast(Context context) {
// TODO Auto-generated constructor stub
super(context);
}
public CustomToast(Context c, View v) {
this(c);
setView(v);
}
/****************** 自己写的接口方法 **************************/
// 让view 一直显示;取消用cancel方法,其他用法同Toast;
public void showAlways() {
Field mTNField = null;
try {
mTNField = Toast.class.getDeclaredField("mTN");
// 获取权限
mTNField.setAccessible(true);
// 得到实例,这里反射不用newinstance;
Object mTN = mTNField.get(this);
try {
// android 4.0以上系统要设置mT的mNextView属性
Field mNextViewField = mTN.getClass().getDeclaredField(
"mNextView");
mNextViewField.setAccessible(true);
mNextViewField.set(mTN, getView());
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
Method showMethod = mTN.getClass().getDeclaredMethod("show", null);
showMethod.setAccessible(true);
showMethod.invoke(mTN, null);
isShowing = true;
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void show() {
// TODO Auto-generated method stub
super.show();
isShowing = true;
}
// 显示多少豪秒自动退出;用了show方法的多态;
public void show(long delayMillis) {
// TODO Auto-generated method stub
// 定时退出
showAlways();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
cancel();
}
}, delayMillis);
}
@Override
public void cancel() {
// TODO Auto-generated method stub
super.cancel();
isShowing = false;
}
// 判断toast是否正在显示
public boolean isShowing() {
return isShowing;
}
/****************结束接口******************/
}
2,测试文件MainActivity.java
public class MainActivity extends Activity {
private Button showtoast, closetoast;
private String TAG = "MainActivity";
ReflectToast1 rToast = null;
private boolean isDestoryed = false;
CustomToast customToast = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
showtoast = (Button) findViewById(R.id.show);
closetoast = (Button) findViewById(R.id.hide);
showtoast.setOnClickListener(new MyOnClickListener());
closetoast.setOnClickListener(new MyOnClickListener());
TextView tvTextView = new TextView(this);
tvTextView.setText("wocalei");
tvTextView.setTextColor(this.getResources().getColor(
android.R.color.holo_blue_dark));
tvTextView.setBackgroundColor(0xffffffff);
customToast = new CustomToast(this);
customToast.setView(tvTextView);
// 这个线程检测isShowing()函数
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while (!isDestoryed) {
Log.i(TAG, "is show = " + customToast.isShowing());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
isDestoryed = true;
}
class MyOnClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.show:
// customToast.show();
// customToast.show(5000);
customToast.showAlways();
break;
case R.id.hide:
customToast.cancel();
break;
default:
break;
}
}
}
}
完美解决问题!