Search code examples
androideventsview

get the view from MotionEvent X,Y


Is there a way to get a reference to the view being touched while inside Activity.dispatchTouchEvent(MotionEvent ev)?

I need to hide a custom RelativeLayout "Keyboard" if user clicks anywhere where it is not an EditText. And since I am using on activity and many fragments each has many view groups and each group has it own many views, some of which are EditTexts, it would be too much work to set an onTouchEvent on each child view or child viewGroup.

In MainActivity, something like this is what I think would be a good way to go.

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    if (mKeyboardLike.getVisibility() == View.VISIBLE) {
        if (!isTouchedEditText(ev.getRawX(), ev.getRawY())) {
            mKeyboardLike.setVisibility(View.GONE);
        }
    }
    return super.dispatchTouchEvent(ev);
}
private boolean isTouchedEditText(int x, int y){//viewFound instanceOf EditText; return true;}

Solution

  • I think this should help you:

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        int x = Math.round(ev.getX());
        int y = Math.round(ev.getY());
        for (int i = 0; i < getChildCount(); i++) {
            if (isEditText(x, y, getChildAt(i))) {
                return true;
            }
        }
    
        return true;
    }
    
    public boolean isEditText(int x, int y, View view) {
        if (view instanceof ViewGroup) {
            for (int i = 0; i < getChildCount(); i++) {
                if (isEditText(x, y, ((ViewGroup) view).getChildAt(i))) {
                    return true;
                }
            }
        } else if (view instanceof EditText) {
            if (x > view.getLeft() && x < view.getRight() && y > view.getTop() && y < view.getBottom()) {
                return true;
            }
        }
        return false;
    }