版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
在开发中经常会碰到如图所示带EditText的需求
烦人的软件盘会自动弹出。
大部分解决都是去AndroidManifest.xml中设置Activity的相关属性。
这里直接给父View给默认焦点就行了。
android:focusable="true"
android:focusableInTouchMode="true"
在父布局中如下所示。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:focusable="true"
android:focusableInTouchMode="true"
android:layout_height="match_parent">
<EditText/>
<EditText/>
<EditText />
<EditText />
</LinearLayout>
这样在启动Activity的时候由于焦点是属于父布局的。EditText并没有获取到焦点。所以不会弹出软键盘。
这时继续点击Edittext外部的时候,焦点还是在EditText上。
但是在日常开发中我们都希望在点击EditText外部的时候自动取消焦点并关闭键盘。在点击EditText时才有焦点。
这就需要进行如下操作:
在Activity中加入如下三段代码即可
EditText editText = null;
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
View v = getCurrentFocus();
if (isShouldHideInput(v, ev)) {//点击editText控件外部
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
assert v != null;
hideInputMethod(this, v);
if (editText != null) {
editText.clearFocus();
}
}
}
return super.dispatchTouchEvent(ev);
}
// 必不可少,否则所有的组件都不会有TouchEvent了
return getWindow().superDispatchTouchEvent(ev) || onTouchEvent(ev);
}
public boolean isShouldHideInput(View v, MotionEvent event) {
if ((v instanceof EditText)) {
editText = (EditText) v;
int[] leftTop = {0, 0};
//获取输入框当前的location位置
v.getLocationInWindow(leftTop);
int left = leftTop[0];
int top = leftTop[1];
int bottom = top + v.getHeight();
int right = left + v.getWidth();
return !(event.getX() > left && event.getX() < right
&& event.getY() > top && event.getY() < bottom);
}
return false;
}
public static void hideInputMethod(Context context, View v) {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
一般放在BaseActivity中即可解决。
附加:
当Dialog中的Edit无法呼出键盘时,给Dialog的view添加
window.clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
代码即可