Ok everyone knows that to hide a keyboard you need to implement:
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
But the big deal here is how to hide the keyboard when the user touches or selects any other place that is not an EditText
or the softKeyboard?
I tried to use the onTouchEvent()
on my parent Activity
but that only works if user touches outside any other view and there is no scrollview.
I tried to implement a touch, click, focus listener without any success.
I even tried to implement my own scrollview to intercept touch events but I can only get the coordinates of the event and not the view clicked.
Is there a standard way to do this?? in iPhone it was really easy.
Here's another variation on fje's answer that addresses the issues raised by sosite.
The idea here is to handle both the down and the up actions in the Activity's
dispatchTouchEvent
method. On the down action, we make note of the currently focused view (if any) and whether the touch was inside it, saving both those bits of info for later.On the up action, we first dispatch, to allow another view to potentially take focus. If after that, the currently focused view is the originally focused view, and the down touch was inside that view, then we leave the keyboard open.
If the currently focused view is different than the originally focused view and it's an
EditText
, then we also leave the keyboard open.Otherwise we close it.
So, to sum up, this works as follows:
EditText
, the keyboard stays openEditText
to anotherEditText
, the keyboard stays open (doesn't close/reopen)EditText
that is not anotherEditText
, the keyboard closesEditText
to bring up the contextual action bar (with the cut/copy/paste buttons), the keyboard stays open, even though the UP action took place outside the focusedEditText
(which moved down to make room for the CAB). Note, though, that when you tap on a button in the CAB, it will close the keyboard. That may or may not be desirable; if you want to cut/copy from one field and paste to another, it would be. If you want to paste back into the sameEditText
, it would not be.when the focused
EditText
is at the bottom of the screen and you long-click on some text to select it, theEditText
keeps focus and therefore the keyboard opens like you want, because we do the "touch is within view bounds" check on the down action, not the up action.Method for show / hide soft keyboard
I hope they have been useful
This is a slightly modified version of fje's answer which mostly worked perfectly.
This version uses ACTION_DOWN so performing a scroll action also closes the keyboard. It also doesn't propagate the event unless you click on another EditText. This means that clicking anywhere outside your EditText, even on another clickable, simply closes the keyboard.
Use OnFocusChangeListener.
For example:
Update: you also may override
onTouchEvent()
in your activity and check coordinates of the touch. If coordinates are outside of EditText, then hide the keyboard.I implemented dispatchTouchEvent in Activity to do this:
and I tested it, works perfect!
Other idea is to override
onInterceptTouchEvent
method on the root view for your Activity.The touch event goes from the front most view on the screen (where the touch event occurred) down the stack of views calling the
onTouch
method until any of the views return true, indicating that the touch event was consumed. As many of the view consumes the touch event by default (that is the case ofEditText
orTextView
, for instance), the event does not get to the Activity's root ViewonTouch
method.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.