最近做添加门店,门店昵称自动根据文字变化去搜索后台数据,但是一搜索软键盘就关闭了,感觉用户体验不太好。一开始根本不知道啥问题,找了半天才发现是网络请求dialog加载导致软件盘隐藏的,后面直接把dialog给注释掉了。忙的做项目没时间查资料。今天网上搜了一下,有其他解决办法,通过人家贴的源码才知道。不得感叹一下:关键时刻还是源码好使啊!

首先说下结论: 

1.AlertDialog和ProgressDialog默认可以和系统软键盘并存与同意屏幕(其实质是并存于同一个window窗口,具体下面会解释) 

2.Dialog以及用户自定义的继承自Dialog的弹出框默认不可以和软键盘并存与同一屏幕

我遇到的就是第二种情况还是对底层不太熟悉,根本不知道啥问题,检查代码都没问题,最后只能把dialog注释掉不显示,浪费好多时间,如果想dialog和软件盘并存的话

2.1Dialog对象设置

Dialog di = new Dialog(MainActivity.this);
di.setTitle("test test");
di.getWindow().setFlags(
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);

2.2自定义继承自Dialog对象的设置

public class LoadingDialog extends Dialog {
...
}
loadDialog = new LoadingDialog(this, R.style.dialog);
loadDialog.getWindow().setFlags(
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);

那么为什么会这样,还是对本质不了解

Activity是什么?Dialog是什么?软键盘的实质是什么?他们三个和Window窗口的关系是什么? 

通过网上查看解释源码得知:

Acitvity的布局是添加在所创建的window窗口中的

dialog需要创建一个属于自己的window窗口

然而软键盘的实质就是一个自定义的Dialog

由于软键盘也是一个自定义dialog,那么实质上就是我们的自定义dialog和软键盘的并存关系了。

最终结论:由于dialog是依附于window窗口存在的,所以是由window的属性控制dialog和软键盘的显示。 

dialog中源码注释已经说明如果需要dialog显示在软键盘之上,就需要为window添加FLAG_ALT_FOCUSABLE_IM这个属性。我们通过继承Dialog自定义的弹出窗口也需要为他们所在的window设置这个属性才可以和软键盘并存。 


郝金刚