EditText 외부 영역 터치 시 키보드 숨기기

seong-hwan Kim
shDev
Published in
4 min readNov 20, 2021

이 글에서는 안드로이드 EditText의 외부 영역을 터치했을 때 소프트 키보드를 숨기는 방법에 대해 소개한다.

안드로이드에서 EditText의 외부 영역을 터치했을 때 키보드가 아래로 사라지는 기능은 이미 많은 앱에서 제공하는 익숙한 기능이며, 앱의 사용자 또한 당연히 이렇게 동작 할 것이라고 생각한다. 하지만 이 기능은 안드로이드 내부적으로 제공되는 기능이 아니기 때문에 개발자가 따로 구현할 필요가 있다.

많이 사용되는 기능인 만큼 조금만 검색하여도 해당 기능을 어떻게 구현할 수 있는지에 대해 많은 정보를 얻을 수 있다. 화면의 루트 레이아웃에 키보드를 숨기는 클릭 리스너를 추가하는 방법도 있고, 포커스를 전달하여 키보드를 숨기는 방법도 찾을 수 있지만 내가 원하는 것은 XML 또는 Activity마다 추가적인 코드를 작성할 필요 없이 일반적으로 적용 가능한 방법이었다.

일반적인 구현 방법

https://dev-gold.tistory.com/108

구글에 키보드를 숨기는 기능에 대해 검색했을 때 쉽게 찾을 수 있는 코드를 가져왔다. 여기서는 Activity의 dispatchTouchEvent를 오버라이드하고 현재 포커스를 가지고 있는 뷰의 터치 영역과 이벤트가 발생한 좌표를 비교하여 소프트 키보드를 숨기고 있다.

이 코드는 단순한 상황이라면 문제 없이 동작한다. 하지만 일부 상황에서 기대하는것 처럼 동작하지 않는 문제가 발생하여 다른 방법을 찾아야만 했다.

문제점 1: 다른 EditText 선택 시 키보드 재등장

위의 코드의 첫 번째 문제점은 화면에서 EditText를 여러 개 사용할 때, 다른 EditText를 선택할 때 마다 키보드가 사라졌다가 다시 등장하는 것이다.

문제가 되는 상황을 구현하면 아래와 같다.

문제점 2: 스크롤 뷰에서 이상 동작

위의 코드를 보면 터치 이벤트의 액션이 ACTION_UP이거나 ACTION_MOVE인 경우 키보드를 숨기게 된다. 때문에 스크롤 뷰 내에서 EditText를 사용할 때 원하는데로 동작하지 않는 문제가 발생하였다.

EditText를 선택하고 스크롤 수행 시 키보드가 자동으로 닫히게 된다. 조건에서 ACTION_MOVE를 제거하더라도 문제는 동일하다. 스크롤이 끝나고 손가락을 떼었을 때 키보드가 자동으로 닫히게 된다.

이것은 내가 원하는 동작이 아니었다. 키보드가 등장하면서 화면의 높이가 줄어드는 만큼 키보드를 열어둔 채 화면을 스크롤하여 좀 더 아래에 있는 EditText를 선택하고 싶었다.

이 문제를 해결하기 위해서는 기존의 코드에서 키보드가 닫히는 조건을 변경할 필요가 있다.

해결 방안

문제점을 해결할 수 있었던 코드는 아래와 같다.

  1. 단순히 ACTION_UP 이벤트에서 키보드를 숨기고 싶지 않았기 때문에 SingleTapUp 제스처를 사용하였다.
  2. 다른 EditText를 터치했을 때 키보드를 가리지 않기 위해서는 기존의 포커스를 가지고 있던 뷰를 저장해야 하였고, prevFocus라는 프로퍼티를 추가하였다.
  3. dispatchTouchEvent에서는 ACTION_UP 이벤트에서 현재 포커스를 가지고 있는 뷰를 저장한다.
  4. onSingleTapUp 리스너에서는 먼저 이전에 포커스를 가지고 있던 뷰의 터치 영역을 계산하고, 현재 터치한 영역이 prevFocus의 터치 영역 밖일 때 키보드를 숨겨야할 지 결정한다.
  5. 현재 포커스를 가지고 있는 뷰가 EditText이면서 이전에 포커스를 가지고 있는 뷰와 다른 뷰라면, 다른 EditText를 선택한 것이므로 리스너를 종료한다.
  6. 현재 포커스를 EditText가 아닌 다른 뷰에서 가지고 있다면 당연히 키보드를 숨겨야 하며, 포커스가 변경되지 않았다면 EditText를 선택한 상태에서 외부 영역을 터치한 것이므로 키보드를 숨긴다.

끝.

--

--