There is the difference in the Keypad behavior between Android and iOS. When a user taps an EditText, the soft keyboard appears. On Android you normally have to press "Done"/"Next" on the keyboard or the device Back button to hide it. On iOS you can often tap anywhere outside the input to dismiss the keyboard — this post shows how to replicate that behavior on Android.
TL;DR
Override dispatchTouchEvent in your Activity and hide the keyboard when the touch occurs outside the focused EditText. See the complete method below.
Problem
On Android, tapping outside an EditText does not automatically dismiss the soft keyboard. If you want the app to behave like iOS (tap outside to dismiss), you must detect touches outside the currently focused EditText and call InputMethodManager.hideSoftInputFromWindow(…).
Solution (Activity)
Override dispatchTouchEvent in the Activity that hosts your EditText(s). The following method checks whether the currently focused view is an EditText, determines whether the touch was outside that view, and hides the keyboard if so.
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
View view = getCurrentFocus();
boolean ret = super.dispatchTouchEvent(event);
if (view instanceof EditText) {
// Re-get focus to use when computing coordinates (guard against changes)
View w = getCurrentFocus();
if (w == null) {
return ret;
}
int[] scrcoords = new int[2];
w.getLocationOnScreen(scrcoords);
float x = event.getRawX() + w.getLeft() - scrcoords[0];
float y = event.getRawY() + w.getTop() - scrcoords[1];
// If the touch action is ACTION_UP and the touch is outside the view bounds
if (event.getAction() == MotionEvent.ACTION_UP &&
(x < w.getLeft() || x >= w.getRight() || y < w.getTop() || y > w.getBottom())) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
// Use the window token of the currently focused view (guarding for null)
View currentFocus = getWindow().getCurrentFocus();
if (currentFocus != null) {
imm.hideSoftInputFromWindow(currentFocus.getWindowToken(), 0);
}
}
}
}
return ret;
}
What this does
- Checks whether the currently focused view is an EditText.
- Computes the touch coordinates relative to the EditText's position on screen.
- If the touch occurred outside the EditText (ACTION_UP), it hides the soft keyboard via InputMethodManager.hideSoftInputFromWindow(…).
Note: If you remove the coordinate checks, the keyboard may not come up the next time you tap the EditText — so keep the bounds checks to ensure normal behavior.
Short hide call (single EditText)
If you already have a reference to the EditText and want to hide the keyboard directly (for example from a click listener), use:
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);
Fragments
If your EditText lives in a Fragment, one approach is:
- Implement the dispatchTouchEvent override in the hosting Activity (the Activity receives touch events before fragments do), or
- Add a touch listener on the fragment's root view and detect taps outside the focused EditText, then hide the keyboard with InputMethodManager as shown above.
Troubleshooting and notes
- Always guard against null from getCurrentFocus() and getWindow().getCurrentFocus() to avoid NullPointerException.
- If your layout moves or you use complex nested views, confirm the coordinate math still applies (getLocationOnScreen is used to normalize coordinates).
- Consider accessibility and UI expectations: tapping to dismiss is convenient but ensure it doesn't interfere with other gestures.
All the best and happy coding. (y)
No comments:
Post a Comment