每个人都知道要隐藏一个键盘,你需要实现:
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
但这里的大问题是如何隐藏键盘时,用户触摸或选择任何其他地方,不是一个EditText或softKeyboard?
我尝试在我的父活动上使用onTouchEvent(),但只有当用户在任何其他视图之外触摸并且没有滚动视图时才有效。
我试图实现一个触摸,点击,焦点监听器,但没有任何成功。
我甚至尝试实现我自己的滚动视图来拦截触摸事件,但我只能得到事件的坐标,而不是视图被单击。
有标准的方法来做这件事吗?在iPhone中,这非常简单。
只需在活动中覆盖下面的代码
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (getCurrentFocus() != null) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}
return super.dispatchTouchEvent(ev);
}
更新:
如果有人需要这个答案的Kotlin版本:
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
if (currentFocus != null) {
val imm = activity!!.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(activity!!.currentFocus!!.windowToken, 0)
}
return super.dispatchTouchEvent(ev)
}
另一个想法是覆盖onInterceptTouchEvent方法在根视图为您的活动。
触摸事件从屏幕上最前面的视图(触摸事件发生的地方)沿着调用onTouch方法的视图堆栈向下移动,直到任何视图返回true,表明触摸事件被消费。由于许多视图默认使用触摸事件(例如,EditText或TextView的情况),事件不会到达活动的根视图onTouch方法。
But, before do this traversal, the touch event travels another path, going from the root view down the view tree until it gets to the front most view. This traversal is done by calling onInterceptTouchEvent. If the method returns true, it intercepts the event... nahhh, but that is a little bit trick, I don't think you want to do that nor to know the details. What you need to know is that you can override this method on the root view for your Activity, and put there the code to hide the keyboard when necessary.
要解决这个问题,你必须首先使用Edittext的setOnFocusChangeListener
edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
Log.d("focus", "focus loosed");
// Do whatever you want here
} else {
Log.d("focus", "focused");
}
}
});
然后你需要做的是覆盖dispatchTouchEvent在活动中包含的编辑文本见下面的代码
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
View v = getCurrentFocus();
if ( v instanceof EditText) {
Rect outRect = new Rect();
v.getGlobalVisibleRect(outRect);
if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) {
Log.d("focus", "touchevent");
v.clearFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
}
return super.dispatchTouchEvent(event);
}
现在会发生的是当用户点击外部时首先dispatchTouchEvent会被调用它会从编辑文本中清除焦点现在你的OnFocusChangeListener会被调用焦点已经改变了现在在这里你可以做任何你想做的希望它能起作用
活动
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
ScreenUtils.hideKeyboard(this, findViewById(android.R.id.content).getWindowToken());
return super.dispatchTouchEvent(ev);
}
ScreenUtils
public static void hideKeyboard(Context context, IBinder windowToken) {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(windowToken, InputMethodManager.HIDE_NOT_ALWAYS);
}