터치 이벤트 간략 정리(onTouchEvent, dispatchTouchEvent, onInterceptTouchEvent)

2021. 5. 18. 15:59모바일/Android_Java

[Android] [펌] 안드로이드의 Touch Event 디스패치 단계

도입

안드로이드의 이벤트 처리 방식에는 윈도우즈와는 다른 특이한 점들이 있다. 이에 안드로이드의 이벤트 디스패치 단계를 정리 해보았다. (이런 정리 싫어하지만 기본기가 중요하므로 정리했다 --)

특히 터치 이벤트에서 ACTION_DOWN은 모든 핸들러의 단계를 거치게 되고 중간에 이를 처리하면, 이어지는 ACTION_MOVE, ACTION_UP 이벤트는 해당 위치까지만 디스패치 되고 그 메소드를 호출하는 구조이다. (여러 하위 구조를 가지는 복잡한 레이아웃에서는 이런 설계가 여러 핸들러를 거치는 오버헤드를 줄이는 효과가 있을 것이다.)

이벤트 전송의 간략한 메카니즘은 상위에서 하위의 dispatcher 호출을 통해서 이벤트가 아래로 전달되고, 최하위에서는 역으로 listener와 handler가 호출되며 dispatcher가 리턴되면서 하위에서 상위로 이벤트가 전달되는 스택 구조이다.

dispatchTouchEvent, onInterceptTouchEvent, onTouch(Listener) ,onTouchEvent 이 정도 메소드로 이벤트를 처리할 수 있는데, 이제부터 콜백 메소드에서 해당 터치 이벤트를 제어(handled, comsumed)할 경우 디스패치 단계가 어떻게 처리되는지 감상해보자...

[이미지1]

설명

ACTION_DOWN 이벤트는 각 단계를 모두 거치면서 자신의 이벤트 셋(DOWN, MOVE, UP)을 처리할 핸들러가 있는지 확인하게 된다.

위 이미지와 같이 특별히 이벤트를 처리하는 곳이 없으면 최상위의 Activity.onTouchEvent가 핸들러인 것 처럼 간주되어 이어지는 ACTION_MOVE와 ACTION_UP 이벤트는 Activity의 dispater에서 Activity의 핸들러로 바로 처리해 버린다.

실제 앱 구현시에는 대부분 위 이미지 중에 4번째 또는 7번째 이미지만 참고하면 될 것 같다.
그림으로 정리하니깐 분량이 많다 -_-; 하지만 다음의 룰을 따른다고 보면 간단하다.

  • onInterceptTouchEvent는 자식의 dispatchTouchEvent가 호출되야 한다면 그 직전에 항상 호출된다.
  • onTouch Listener는 onTouchEvent Handler가 호출되기 직전에 항상 호출된다.
  • Listener가 이벤트를 처리해서 true(consumed)를 리턴하면 이어지는 Handler는 호출되지 않는다.
  • dispatchTouchEvent는 하위의 dispatchTouchEvent를 호출한 이후에 자신의 Listener, Handler를 호출해서 이벤트를 전달한다.
  • 하위의 dispatchTouchEvent가 true(consumed)를 리턴하면, 이어지는 자신의 Listener, Handler를 호출되지 않는다.
  • Listener 또는 Handler에서 ACTION_DOWN에 대해 true(consumed)를 리턴하면, 해당하는 dispatchTouchEvent도 true(consumed)를 리턴하게 된다.
  • 위의 경우에 이어지는 ACTION_MOVE와 ACTION_UP은 해당 dispatchTouchEvent까지 전달되어 하위로 전달없이 바로 해당 Listener 또는 Handler를 호출한다.

이상 아래 이미지들을 보면서 터치 이벤트에 대해 공부해보자