2016년 9월 27일 화요일

[안드로이드] 터치 이벤트 흐름

안드로이드는 뷰의 터치 이벤트를 처리하는 3가지 방법이 있다.
 - 엑티비티에서 onTouchEvent 메서드 재정의
 - 이벤트를 처리하고자 하는 뷰의 서브클래스에서 onTouchEvent 메서드 재정의
 - 처리하고자 하는 뷰에 View.OnTouchListener 리스너 인터페이스를 등록

이벤트 처리의 흐름

엑티비티에서의 이벤트 처리

엑티비티는 onTouchEvent 메서드를 재정의하면 모든 뷰의 터치이벤트를 받을 수 있다.

뷰에서의 이벤트 처리

onTouchEvent 메서드를 재정의하거나, OnTouchListener 인터페이스를 등록함으로써, 해당 뷰의 이벤트만 처리할 수 있다.
 - onTouchEvent 메서드를 재정의하려면 상속받아서 서브클래스를 구성해야 하기에 번거롭다.
 - OnTouchListener를 등록하면 인터페이스를 구현한 메서드에서 터치이벤트를 받을 수 있으므로 상속이 필요없다.
만약 2가지 방법이 다 구현되어 있다면??
 - OnTouchListener의 메서드(onTouch) -> onTouchEvent의 순서로 호출된다.
 - onTouch 메서드가 true를 리턴하면, onTouchEvent는 이벤트를 받지 못한다. 

Activity, ViewGroup, View 사이의 이벤트 처리

화면이 다음과 같이 구성되어 있을 때, 기본적인 터치 이벤트의 흐름은 다음과 같다.
Activity(dispatchTouchEvent)              : 하위 dispatchTouchEvent 호출
  ViewGroup(dispatchTouchEvent)       : onInterceptTouchEvent 호출
    ViewGroup(onInterceptTouchEvent) : 하위 dispatchTouchEvent 호출
    View(dispatchTouchEvent)              : 자신의 이벤트 핸들러 메서드 호출
      View(onTouch)                           : 이벤트 처리 & 처리여부 리턴
      View(onTouchEvent)                    : 이벤트 처리 & 처리여부 리턴
    View(dispatchTouchEvent)              : 자신의 이벤트 핸들러 메서드의 결과값을 리턴
    ViewGroup(onTouch)                     : 이벤트 처리 & 처리여부 리턴
    ViewGroup(onTouchEvent)             : 이벤트 처리 & 처리여부 리턴
  ViewGroup(dispatchTouchEvent)       : 자신 or 하위 레이어의 결과값을 리턴
  Activity(onTouchEvent)                    : 이벤트 처리 & 처리여부 리턴
Activity(dispatchTouchEvent)              : 자신 or 하위 레이어의 결과값을 리턴

- Aictivity, ViewGroup, View는 모두 dispatchTouchEventonTouchEvent 메서드를
  가지고 있다.
- ViewGroup에는 추가적으로 onInterceptTouchEvent 메서드가 있다.
- 이벤트가 발생하면 각 레이어의 dispatchTouchEvent가 가장 먼저 호출된다.
  dispatchTouchEvent의 역할은 하위 레이어의 dispatchTouchEvent를 호출하고,
  하위 레이어가 터치 이벤트를 처리했는지 결과를 받아서 처리하지 않은 경우
  자기 자신의 이벤트 처리 메서드(onTouch, onTouchEvent) 메서드로 이벤트를 보낸다.
  그리고는 이벤트 처리 여부를 상위 dispatchTouchEvent에 리턴한다.
- onInterceptTouchEvent는 ViewGroup의 dispatchTouchEvent의 로직을 대신 담당하여,
  자신에게 속한 하위뷰에게 이벤트를 전달할지 결정한다.
- 모든 메서드는 리턴값이 boolean형인데 true일 경우 이벤트를 처리했음을 의미하고,
  false일 경우 이벤트가 처리되지 않았음을 의미한다.

댓글 없음:

댓글 쓰기