这里我的解决思路就是通过事件的分发来判断手指点下的位置,是不是editText。如果点击的是editText那么就按照原来正常进行;如果点击的不是editText那么就应该让editText失去焦点并收起键盘。所以一共有三个点:
- 在哪里截取点击事件并进行处理?
- 如何判断点击位置是否为editText的位置?
- 如何收起软键盘并让editText失去焦点?
一个一个来看:
首先我们可以在Activity的dispatchTouchEvent方法中截取点击事件。
至于为什么,这个是关于点击事件分发的相关内容;简单来说就是每次我们手点击屏幕的时候,系统会生成一个点击事件event并通过dispatchTouchEvent方法来处理,event中就包含有点击的坐标。具体详细的内容有兴趣的读者可以自行了解,这里就不多说了。
上文说了通过event可以得到点击的位置,那editText的位置呢?通过getCurrentFocus这个方法可以可以获取到当前拥有焦点的view,再通过getLocationInWindow可以获取到在window中的位置;然后进行判断就可以了。如果当前拥有焦点的view不是editText的话则不需要判断。
这里通过InputMethodManager的hideSoftInputFromWindow方法就可以收起了。
这就是大体的思路,然后接下来看代码实现:
public class EditActivity extends AppCompatActivity {
private TextInputEditText textInputEditText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit);
textInputEditText = findViewById(R.id.textInputEditText_main);
}
//时间分发方法重写
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
//如果是点击事件,获取点击的view,并判断是否要收起键盘
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
//获取目前得到焦点的view
View v = getCurrentFocus();
//判断是否要收起并进行处理
if (isShouldHideKeyboard(v, ev)) {
hideKeyboard(v.getWindowToken());
}
}
//这个是activity的事件分发,一定要有,不然就不会有任何的点击事件了
return super.dispatchTouchEvent(ev);
}
//判断是否要收起键盘
private boolean isShouldHideKeyboard(View v, MotionEvent event) {
//如果目前得到焦点的这个view是editText的话进行判断点击的位置
if (v instanceof EditText) {
int[] l = {0, 0};
v.getLocationInWindow(l);
int left = l[0],
top = l[1],
bottom = top + v.getHeight(),
right = left + v.getWidth();
// 点击EditText的事件,忽略它。
return !(event.getX() > left) || !(event.getX() < right)
|| !(event.getY() > top) || !(event.getY() < bottom);
}
// 如果焦点不是EditText则忽略,这个发生在视图刚绘制完,第一个焦点不在EditText上
return false;
}
//隐藏软键盘并让editText失去焦点
private void hideKeyboard(IBinder token) {
textInputEditText.clearFocus();
if (token != null) {
//这里先获取InputMethodManager再调用他的方法来关闭软键盘
//InputMethodManager就是一个管理窗口输入的manager
InputMethodManager im = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (im != null) {
im.hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS);
}
}
}
}
参考:https://blog.csdn.net/weixin_43766753/article/details/103511807