每个人都知道要隐藏一个键盘,你需要实现:
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
但这里的大问题是如何隐藏键盘时,用户触摸或选择任何其他地方,不是一个EditText或softKeyboard?
我尝试在我的父活动上使用onTouchEvent(),但只有当用户在任何其他视图之外触摸并且没有滚动视图时才有效。
我试图实现一个触摸,点击,焦点监听器,但没有任何成功。
我甚至尝试实现我自己的滚动视图来拦截触摸事件,但我只能得到事件的坐标,而不是视图被单击。
有标准的方法来做这件事吗?在iPhone中,这非常简单。
非常困难的决定。我建议一个更简单的解决办法。
在onViewCreated中,我们为整个视图设置了一个setOnClickListener,并从EditText中删除焦点,以及删除键盘。
片段中的例子。Java。
@Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
nameTextInputEditText = view.findViewById(R.id.NameTextInputEditText);
view.setOnClickListener(v -> {
nameTextInputEditText.clearFocus();
InputMethodManager imm = (InputMethodManager) requireActivity().getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
});
}
另一个想法是覆盖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会被调用焦点已经改变了现在在这里你可以做任何你想做的希望它能起作用
setupUI((RelativeLayout) findViewById(R.id.activity_logsign_up_RelativeLayout));
将该方法传递到布局文件中。您必须选择常用的XML布局文件。
因为,键盘隐藏适用于整个布局。
public void setupUI(View view) {
// Set up touch listener for non-text box views to hide keyboard.
if (!(view instanceof EditText)) {
view.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
hideSoftKeyboard(Your Context); // Pass your context
return false;
}
});
}
//If a layout container, iterate over children and seed recursion.
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
View innerView = ((ViewGroup) view).getChildAt(i);
setupUI(innerView);
}
}
}