
OnTouchListener는 Android에서 뷰(View)의 터치(터치스크린 입력)를 직접 처리하기 위해 사용하는 인터페이스입니다. 뷰에 붙여 터치 이벤트를 가로채고 원하는 동작을 구현할 수 있게 해줍니다. 주요 내용 요약 - 인터페이스 이름: View.OnTouchListener - 핵심 메서드: boolean onTouch(View v, MotionEvent event) - v: 터치가 발생한 뷰 - event: 터치 이벤트 정보(MotionEvent) - 반환값 의미: - true: 이벤트를 여기서 소비(handled)함. 이후의 다른 핸들러(예: 뷰의 기본 onTouchEvent, 부모의 터치 처리 등)에는 전달되지 않음. - false: 이벤트를 소비하지 않음. 이후 시스템/뷰가 기본적으로 처리하도록 전달됨(예: 클릭 처리). - 설치 방법: view.setOnTouchListener(listener) MotionEvent에서 자주 사용하는 값 - 액션: event.getActionMasked() 혹은 event.getAction() - MotionEvent.ACTION_DOWN, ACTION_MOVE, ACTION_UP, ACTION_CANCEL 등이 주요 액션 - 멀티터치 관련: ACTION_POINTER_DOWN, ACTION_POINTER_UP - 좌표: - event.getX(), event.getY(): 뷰 내부 좌표 - event.getRawX(), event.getRawY(): 화면 전체 좌표 - 포인터 정보: - event.getPointerCount(), event.getPointerId(index), getX(index) 등 언제 쓰나 - 드래그/스와이프처럼 세밀한 터치 추적이 필요할 때 - 터치 위치나 움직임 기반의 커스텀 동작 구현 시 - 기본 클릭 외에 제스처를 직접 감지하고자 할 때(단순한 제스처는 GestureDetector 권장) OnTouchListener와 관련된 유의점(베스트 프랙티스) - 반환값을 신중히 선택: true로 반환하면 뷰의 onClick이나 기본 동작이 호출되지 않을 수 있음. 클릭을 유지하고 싶다면 특정 조건에서만 true 반환. - 접근성: 터치로 클릭 동작을 직접 처리하고 onClick을 호출하지 않는 경우, 접근성(예: TalkBack)을 위해 performClick()을 명시적으로 호출해주는 것이 좋음. - ViewGroup과의 상호작용: 부모가 터치를 가로채는 경우(onInterceptTouchEvent)도 존재. 복잡한 제스처는 부모/자식 간 이벤트 흐름을 고려. - GestureDetector 사용 검토: 탭/플링/스와이프 등 표준 제스처는 GestureDetector를 사용하면 구현이 더 쉬움. - 멀티터치 처리: 여러 손가락을 다뤄야 하면 포인터 인덱스/아이디를 올바르게 관리해야 함. 간단한 예시 (Java) - 드래그 예: 뷰를 터치로 이동시키는 간단한 구현 View.setOnTouchListener(new View.OnTouchListener() { float dX, dY; @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: dX = v.getX() - event.getRawX(); dY = v.getY() - event.getRawY(); return true; // 드래그를 처리하므로 이벤트 소비 case MotionEvent.ACTION_MOVE: v.setX(event.getRawX() + dX); v.setY(event.getRawY() + dY); return true; case MotionEvent.ACTION_UP: v.performClick(); // 접근성용 권장 호출 return true; default: return false; } } }); Kotlin 예시 view.setOnTouchListener { v, event -> when (event.actionMasked) { MotionEvent.ACTION_DOWN -> { // 초기화 true } MotionEvent.ACTION_MOVE -> { // 이동 처리 true } MotionEvent.ACTION_UP -> { v.performClick() true } else -> false } } 마지막으로 - OnTouchListener는 터치 이벤트를 세밀하게 제어할 수 있게 해주는 강력한 도구지만, 기본 이벤트 흐름(클릭, 포커스, 부모의 터치 가로채기 등)을 깨뜨릴 수 있으므로 반환값과 접근성 처리에 주의해야 합니다.