쾌락코딩

RxBinding을 사용하여 안드로이드 버튼 중복 클릭 방지하기

|

버튼을 터치시 발생하는 이벤트를 처리할 때, 대부분의 경우 중복 터치 이벤트를 막아야 한다. 예를 들어 송금 버튼이 있을 경우 사용자가 아주 빠른시간에 연속해서 두번 터치한다고 해서 돈이 두 번이나 빠져나가서는 곤란하다. RxBinding을 사용하면 쉽게 중복터치를 차단할 수 있다(꼭 중복 터치 뿐만 아니라 RxJava의 훌륭한 메서드들을 안드로이드 UI에 적용할 수 있으니 꽤나 유용하다).

debounce() VS throttleFirst()

중복 터치 이벤트를 막기 위해서는 debounce()throttleFirst메서드를 사용할 수 있다. 둘다 중복 터치를 차단 할 수는 있지만 미세한 차이가 있기 때문에 자세히 알아보자.

debounce()

debounce

debounce()는 특정 시간(예를들어 1초)을 정해주면, 특정 이벤트가 발생한 직후부터 1초 동안은 어떤 이벤트도 발생하지 않아야만 1초 전에 발생한 이벤트가 실행된다. 만약 사용자가 처음 버튼을 클릭한 이후 0.5초 이후에 또 버튼을 클릭했다면, 처음 버튼을 눌렀던 이벤트는 없었던 일이 되어버리고 0.5초 뒤에 누른 두 번째 버튼 이벤트를 다시 1초동안 감시한다. 두 번째 누른 버튼 이벤트 이후 1초 동안 아무 이벤트도 없었다면 그때서야 두 번째 버튼 이벤트만 발생한다.

throttleFirst()

throttleFirst

throttleFirst() 역시 특정 시간(예를들어 1초)을 정해주어야 한다. debounce()와는 다르게 특정 이벤트가 발생한 직후 곧바로 이벤트가 발생하고 이후 1초 동안은 어떤 이벤트가 들어와도 무시된다. 즉 사용자가 “송금” 버튼을 한 번 클릭한 이후 0.5초 뒤에 한 번 더 클릭했다면 두 번째 클릭은 무시된다. 주의해야할 점은 사용자가 처음 “송금” 버튼을 누르고 나서 1.1초뒤에 한 번더 클릭 할 경우에는 이벤트가 두 번 작동한다는 것이다. 이 부분은 바로 아래에서 조금더 다뤄보자.

무엇이 더 적합할까?

위에서 debounce()throttleFirst()를 알아 보았다. 둘다 간단하게 중복 터치를 막을 수 있는데, 뭐가더 좋을까?

사실 정답은 없다. 정해진 답은 없지만 처해진 상황에 따라 더 적합한 메서드를 선택해야 한다.

“송금” 버튼을 클릭한 이후 서버로 부터 응답을 받아오는 시간이 너무 오래걸린다(3초)고 가정해보자. “송금”버튼을 누르고 서버로부터 응답을 받고 나면 화면이 전환되어야 하는데 사용자에게 3초라는 시간은 너무 긴 시간이다. “버튼눌렀는데 왜 안넘어가지? 버튼이 안눌렸나? 다시눌러야지” 라며 2초 후에 또 버튼을 누를 것이다.

위의 상황에서 debounce()에 시간을 3초로 걸어놓았을 경우를 생각해 보자. 사용자가 성격이 너무 급해서 2초 마다 버튼을 클릭하며 “아 왜이렇게 느린거야!?”라고 소리칠 수도 있다. 이 사용자가 2초 마다 버튼을 계속 클릭한다면 절대 다음 화면으로 넘어갈 수 없다. 언젠가는 이 사용자가 버튼 클릭 이후 3초를 기다리길 바랄 수 밖에 없다.

이번엔 throttle()에 시간을 3초로 걸어놓았을 경우를 생각해보자. 성격 급한 사용자가 처음 버튼 클릭 후 2초뒤에 또 버튼을 클릭해도 그 이벤트는 무시된다. 즉 맨 처음 누른 그 시점에만 곧 바로 이벤트가 적용되어 서버로 요청이 날라갔고, 2초 뒤에 누른 이벤트는 무시된다. 대부분 경우 버튼 중복 터치 이벤트 방지는 throttle()이 좋은 선택이 될 수가 있지만, 서버로 부터의 응답이 조금 늦어져서 3.2초가 걸릴 경우 3.1초에 클릭한 중복 터치 이벤트는 무시하지 못해서 송금이 될 것이다. 따라서 버튼 클릭 이후 해당 버튼이 없어지거나 화면이 바뀐다면 throttle()의 시간을 넉넉히 잡아주는 것이 좋아보인다.

사실은…

사실 debounce()는 버튼 중복 클릭 이벤트 방지에도 쓰이긴 하지만, 더 적합한 곳은 주소 검색시 자동완성 기능 같은 곳에 적합한것 같다. 나는 최근에 안드로이드에서 카카오 API를 사용하여 주소 입력시 관련 주소들을 나열해주는 자동완성 기능을 개발했는데, 이때 debounce를 사용해서 효율성을 높혔다. 내가 찾고 싶은 것은 판교역인데, ㅍ,파,판 … 을 입력 할 때마다 카카오에 쿼리를 날려서 데이터 낭비가 심한 상황이 생겼다. 이때 적당히 debounce를 준다면 매번 쿼리를 날리지 않게 되고, 사용자가 입력을 하다가 아주 잠시 멈추는 순간에 추천 검색어가 뜨게 된다.

Comments