Hide the Soft Keyboard and Remove Focus from EditText in Android
Tags: android, java, ux
Published: 2023-05-31 11:44:53

Hello **Android Developers**,

If you're reading this, chances are you're looking for a way to improve your app's user experience by managing the visibility of the soft keyboard and the focus of EditText views more effectively. You might be wondering how to automatically hide the keyboard and remove focus from an EditText (or its subclass) when a user clicks elsewhere in your app. In this post, we'll go through a simple solution for this common situation.

---

## The dispatchTouchEvent() Method

Before diving into the solution, let's introduce dispatchTouchEvent(). This is an Android Activity class method called whenever a touch event is dispatched (i.e., when a user interacts with the touch screen). The touch event contains key information about the interaction, such as the location and type of touch (e.g., down, move, up).

---

### The Solution Explained

Here's the code snippet that handles this UX enhancement:


```java
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        View v = getCurrentFocus();
        if (v instanceof EditText) {
            Rect outRect = new Rect();
            v.getGlobalVisibleRect(outRect);
            if (!outRect.contains((int) event.getRawX(), (int) event.getRawY())) {
                v.clearFocus();
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
            }
        }
    }
    return super.dispatchTouchEvent(event);
}
```

---


## Let's break this down:

**Checking for ACTION_DOWN:** We're interested in the 'down' event, which signifies the start of a touch (i.e., the user's finger first makes contact with the screen). We check for this event with if (event.getAction() == MotionEvent.ACTION_DOWN).

**Identifying the Current Focus:** The getCurrentFocus() function is used to identify the view currently in focus - this is usually the view the user is or has last interacted with.

**Verifying if it's an EditText:** The if (v instanceof EditText) statement checks if the currently focused view is an instance of EditText. We want to ensure the following operations (like hiding the keyboard) only happen when an EditText loses focus.

**Defining the Touch Boundary**: We create a Rect object (representing a rectangle) to denote the visible area of the EditText view on the screen.

**Detecting a Touch Outside EditText:** We then check if the touch event is within this rectangle. If it's not, it means that the user has touched outside of the EditText view.

**Removing Focus and Hiding Keyboard:** If the touch is detected outside the EditText, we clear the focus from the EditText and fetch the Input Method Manager (a system service that deals with the soft keyboard). We use this to hide the keyboard.

**Passing on the Event:** Finally, we pass the touch event on to the super class's dispatchTouchEvent(). This is crucial as the touch event may need further processing by other views or the system.

---


## Working with TextInputEditText

For those wondering about TextInputEditText (a subclass of EditText), fear not! This code works perfectly well for TextInputEditText views as well. If you wish to specifically apply this functionality to TextInputEditText views, you can replace if (v instanceof EditText) with if (v instanceof TextInputEditText).


---

## Wrapping Up

This simple yet effective method can drastically improve the user experience of your Android app, particularly when working with forms or text inputs. Remember, a seamless user experience often leads to higher user satisfaction.

> Keep coding and enhancing!