Ok everyone knows that to hide a keyboard you need to implement:
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hi
I'm aware that this thread is quite old, the correct answer seems valid and there are a lot of working solutions out there, but I think the approach stated bellow might have an additional benefit regarding efficiency and elegance.
I need this behavior for all of my activities, so I created a class CustomActivity inheriting from the class Activity and "hooked" the dispatchTouchEvent function. There are mainly two conditions to take care of:
This is my result:
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if(ev.getAction() == MotionEvent.ACTION_UP) {
final View view = getCurrentFocus();
if(view != null) {
final boolean consumed = super.dispatchTouchEvent(ev);
final View viewTmp = getCurrentFocus();
final View viewNew = viewTmp != null ? viewTmp : view;
if(viewNew.equals(view)) {
final Rect rect = new Rect();
final int[] coordinates = new int[2];
view.getLocationOnScreen(coordinates);
rect.set(coordinates[0], coordinates[1], coordinates[0] + view.getWidth(), coordinates[1] + view.getHeight());
final int x = (int) ev.getX();
final int y = (int) ev.getY();
if(rect.contains(x, y)) {
return consumed;
}
}
else if(viewNew instanceof EditText || viewNew instanceof CustomEditText) {
return consumed;
}
final InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(viewNew.getWindowToken(), 0);
viewNew.clearFocus();
return consumed;
}
}
return super.dispatchTouchEvent(ev);
}
Side note: Additionally I assign these attributes to the root view making it possible to clear focus on every input field and preventing input fields gaining focus on activity startup (making the content view the "focus catcher"):
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final View view = findViewById(R.id.content);
view.setFocusable(true);
view.setFocusableInTouchMode(true);
}