最近项目需求,点击弹窗以外区域先判断软键盘是否隐藏,如果软键盘显示,则先隐藏软键盘,否则直接退出弹窗。为此查了好多资料,发现对于软键盘是否显示并无对应的接口,网上也有篇文章对各种方法进行了测试,我也测试过确实没什么用。参考:判断软键盘是否显示的各种方法测试结果 对于以上文章当中有一种判断方法,可以采用,但是不是很通用。1.需要根据屏幕中软键盘的高度确定以下2/3这个值,对于有横竖屏软键盘高度不一,就不好定了,还要判断横竖屏状态,标题栏的高度改变了对这个比例值可能也有影响。2.rect.bottom这个参数获取的值,我还没整明白,各种情况下获取的值都不一定是可视区域的bottom值。(因为项目很赶,当时没来得及记录具体情况)
参考资料
/**
*判断输入法是否显示
* @return
*/
private boolean isSoftShowing() {
//获取当前屏幕内容的高度
int screenHeight = getWindow().getDecorView().getHeight();
//获取View可见区域的bottom
Rect rect = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
return screenHeight * 2 / 3 > rect.bottom;
}
具体原理解析如下:
Android获取窗口可视区域大小: getWindowVisibleDisplayFrame()
于是想了好久,绝对另辟蹊径了!!!希望可以给大家一点提示啦哈~(此方法只对软键盘弹出时会将控件顶上去的方式有用)
既然如此就好办了,以含编辑框的弹窗为例。
在弹窗的onCreate()方法里面,创建编辑框EditText时,使用view.post或view.postDelayed记录绘制View时编辑框的Y坐标。每次点击弹窗区域以外区域判断一下编辑框的Y坐标是否等于原始坐标,以此判断软键盘是否弹出。
【注意:如果直接在onCreate()里获取编辑框的坐标值会为0,因为控件没有绘制完成,还没有attach到window上,所以获取的坐标值为0,具体解决方案一般是用view.post或者view.postDelayed来解决。具体解析可参考超详细!!Android View.post和View.postDelayed view.post是主线程执行完成后立刻调用,view.postDelayed相当于定时器,主线程执行完后延迟多少秒调用。】
事不宜迟,开干咯~
主要的代码如下:
//记录editText的原始Y坐标
editText.post(new Runnable() {
@Override
public void run() {
//获取editText的Y坐标
int[] location=new int[2];
editText.getLocationOnScreen(location);
int positionY=location[1];
//记录初始位置
posY=positionY;
android.util.Log.d(TAG, "初始位置--- "+positionY);//posY===902(坐标原点是左上角哦~~~)
}
});
//弹窗点击事件
@Override
public boolean onTouchEvent( MotionEvent event) {
switch (event.getAction()){
//MotionEvent
case MotionEvent.ACTION_DOWN:
//判断点击区域是否为弹窗区域以外
if (isOutOfBounds(getContext(),event)){
//获取当前控件的Y坐标
int[] location=new int[2];
editText.getLocationOnScreen(location);
int positionY=location[1];
Log.d(TAG, "onTouchEvent: 当前位置---"+positionY);//positionY===503(软键盘弹出后的位置)
if (posY!=positionY){
final InputMethodManager imm = (InputMethodManager)mContext.
getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);//软键盘隐藏
editText.clearFocus();//取消光标焦点
Log.d(TAG, "onTouchEvent: 点击区域外部软键盘隐藏");
}else {
Log.d(TAG, "onTouchEvent: 退出");
dismiss();
}
}
break;
}
return false;
}
/**
* 判断点击区域是否在弹窗区域外
* @param context
* @param event
* @return
*/
public boolean isOutOfBounds(Context context, MotionEvent event) {
final int x = (int) event.getX();
final int y = (int) event.getY();
final int slop = ViewConfiguration.get(context).getScaledWindowTouchSlop();
final View decorView = getWindow().getDecorView();
return (x < -slop) || (y < -slop) || (x > (decorView.getWidth() + slop))
|| (y > (decorView.getHeight() + slop));
}