My layout contains ListView
, SurfaceView
and EditText
. When I click on the EditText
, it receives focus and the on-screen keyboard pops up. When I click somewhere outside of the EditText
, it still has the focus (it shouldn't).
I guess I could set up OnTouchListener
's on the other views in layout and manually clear the EditText
's focus. But seems too hackish...
I also have the same situation in the other layout - list view with different types of items, some of which have EditText
's inside. They act just like I wrote above.
The task is to make EditText
lose focus when user touches something outside of it.
I've seen similar questions here, but haven't found any solution...
Ken's answer works, but it is hacky. As pcans alludes to in the answer's comment, the same thing could be done with dispatchTouchEvent. This solution is cleaner as it avoids having to hack the XML with a transparent, dummy FrameLayout. Here is what that looks like:
This simple snippet of code does what you want
As @pcans suggested you can do this overriding
dispatchTouchEvent(MotionEvent event)
in your activity.Here we get the touch coordinates and comparing them to view bounds. If touch is performed outside of a view then do something.
Also it's not necessary to check view existance and visibility if your activity's layout doesn't change during runtime (e.g. you don't add fragments or replace/remove views from the layout). But if you want to close (or do something similiar) custom context menu (like in the Google Play Store when using overflow menu of the item) it's necessary to check view existance. Otherwise you will get a
NullPointerException
.I tried all these solutions. edc598's was the closest to working, but touch events did not trigger on other
View
s contained in the layout. In case anyone needs this behavior, this is what I ended up doing:I created an (invisible)
FrameLayout
called touchInterceptor as the lastView
in the layout so that it overlays everything (edit: you also have to use aRelativeLayout
as the parent layout and give the touchInterceptorfill_parent
attributes). Then I used it to intercept touches and determine if the touch was on top of theEditText
or not:Return false to let the touch handling fall through.
It's hacky, but it's the only thing that worked for me.
The best way is use the default method
clearFocus()
You know how to solve codes in
onTouchListener
right?Just call
EditText.clearFocus()
. It will clear focus inlast EditText
.Building on Ken's answer, here's the most modular copy-and-paste solution.
No XML needed.
Put it in your Activity and it'll apply to all EditTexts including those within fragments within that activity.