因为android系统提供的Toast无法获得焦点,当toast提示弹出的时候,下面的view仍然可以获得焦点,并执行触摸事件.
目前有两种实现方法:1.使用一个布局覆盖原有的view ,并设置为透明,上面放置一个textview,用于提示;
2.使用dialog来实现toast的提示,并且可以正确的让dialog 获得焦点,当dialog 显示的时候,后面的view无法进行点击,同时,当activity被销毁的时候,dailog 也被销毁了,不会出现多个toast类似折叠的效果.
代码示例:
public class DialogToast extends Dialog implements Runnable{
private static final int SUCCESS = 0;
private int mShowTime;
private Context mContext;
//toast提示
private LinearLayout ll_toast;
//toast 提示语
private TextView tv_toast;
//加载进度条
private RelativeLayout rl_loading;
//定义一个dialog
private Dialog mDialog;
//声明一个handler
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case SUCCESS:
mDialog.dismiss();
break;
}
super.handleMessage(msg);
}
};
public DialogToast(Context context) {
super(context,R.style.ToastDialog);
this.mContext = context;
mDialog = new Dialog(mContext,R.style.ToastDialog);//自定义Dialog的样式
//点击外部不消失
mDialog.setCancelable(false);
//声明布局文件
initView();
//初始化UI控件
initViews();
//获得dialog的显示的大小
initData();
//处理用户点击物理返回键的时候,让dialog隐藏
// initClick();
}
/**
* 处理dialog的显示样式
* */
private void initData() {
Window dialogWindow = mDialog.getWindow();//得到要显示的窗口
//得到窗口的属性
WindowManager.LayoutParams winLayoutParams = dialogWindow.getAttributes();
dialogWindow.setGravity(Gravity.CENTER);
//重定义窗口的大小
winLayoutParams.width = LayoutParams.WRAP_CONTENT;
winLayoutParams.height = LayoutParams.WRAP_CONTENT;
dialogWindow.setAttributes(winLayoutParams);
}
// /**
// * 处理用户点击物理返回键的时候,让dialog隐藏
// * */
// private void initClick() {
//
// mDialog.setOnKeyListener(new OnKeyListener()
// {
// @Override
// public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event)
// {
// if(event.getAction() == KeyEvent.ACTION_DOWN)
// {
// switch(keyCode)
// {
// case KeyEvent.KEYCODE_BACK:
// dismiss();
// break;
// }
// }
// return false;
// }
// });
// }
/**
* 添加布局文件
* */
private void initView() {
mDialog.setContentView(R.layout.dialog_toast);
}
/**
* 初始化UI控件
* */
private void initViews() {
ll_toast = (LinearLayout)mDialog.findViewById(R.id.ll_toast);
tv_toast = (TextView)mDialog.findViewById(R.id.tv_toast);
rl_loading = (RelativeLayout)mDialog.findViewById(R.id.rl_loading);
}
/**
* 设置显示的时长和显示的toast的内容
*
* */
public void showTimeAndMessage(CharSequence text,int time){
ll_toast.setVisibility(View.VISIBLE);
mShowTime = time;
tv_toast.setText(text);
}
/**
* 设置显示正在加载
* */
public void showLoading(){
ll_toast.setVisibility(View.GONE);
rl_loading.setVisibility(View.VISIBLE);
}
/**
* 子线程,休眠一段时间后,发送handler ,使得dialog消失.
* */
@Override
public void run() {
while(true){
try{
Thread.sleep(mShowTime);
dialogCancel();
}catch(Exception e){
e.printStackTrace();
}
}
}
/**
*
* 显示加载进度条
* */
public void showDialog(){
mDialog.show();
}
/**
* 隐藏dailog
* */
public void dismiss(){
if(mDialog.isShowing()){
mDialog.dismiss();
}
}
/**
* 显示toast
* */
public void showToast(){
mDialog.show();
new Thread(this).start();
}
/**
* 取消显示dialog
* */
public void dialogCancel(){
Message msg = Message.obtain();
msg.what = SUCCESS;
handler.sendMessage(msg);
}
}
style文件的定义如下:
<!-- toastdialog -->
<style name="ToastDialog" parent="android:style/Theme.Dialog">
<!-- 背景颜色及透明程度 -->
<item name="android:windowBackground">@android:color/transparent</item>
<!-- 是否有标题 -->
<item name="android:windowNoTitle">true</item>
<!-- 是否浮现在activity之上 -->
<item name="android:windowIsFloating">true</item>
<!-- 是否模糊 -->
<item name="android:backgroundDimEnabled">false</item>
<!-- 取消边框 -->
<item name="android:windowFrame">@null</item>
</style>
在需要的地方去调用该方法:
DialogToast dailog = new DialogToast();
dailog.showLoading();
dailog.show();//显示
//取消dialog
dailog.dialogCancel();