BLOG ARTICLE GestureDetector | 1 ARTICLE FOUND

  1. 2010.07.30 Android GestureDetector 간략한 설명 (1)

Smart Phone (Mobile)/Android 2010.07.30 23:01

어플리케이션에서 모션 이벤트 중의 하나로 제스쳐라는 것이 있다.
일반적인 터치 이벤트는 DOWN - MOVE - UP의 단계를 거치면서 사용자가 어떤 동작을 입력하는지 감지 할 수 있다.
그럼 이 일련의 사용자 모션들을 조합하여 사용자가 입력하였다면 그 조합이 어떠한 동작인지 알 수도 있다.
이때 사용자의 조합된 모션(제스쳐)를 쉽게 판별하기 위해서 Android에서 제공하는 것이 GestureDetector 클래스 입니다.

GestureDetector는 두 가지 Listener를 가지고 있습니다.
    - interface GestureDetector.OnDoubleTapListener
    - interface GestureDetector.OnGestureListener
자세한 설명은 Reference를 보시면 됩니다.
    - http://developer.android.com/reference/android/view/GestureDetector.html
OnDoubleTapListener는 이름 그대로 두번 터치 했을 때, OnGestureListener는 일반적인 제스쳐들, 한번 터치나 스크롤 관련 Listener입니다.
그리고 저 두 가지 interface를 모두 가진 녀석이 있습니다.
    - class GestureDetector.SimpleOnGestureListener
보통 SimpleOnGestureListener만 extends 하면 모든 제스쳐를 다 사용 할 수 있습니다.

사용법도 매우 간단합니다. GestureDetector를 만들기만 하면 됩니다.
    // GestureDetector를 만들 때 GestureListener를 등록 
    mGestureDetector = new GestureDetector(this, new SimpleGestureListener());
    // 감시할 MotionEvent를 onTouchEvent에 넣어 주면 GetstureListener가 호출이 된다.
    mGestureDetector.onTouchEvent(event);

각 제스쳐의 이벤트는 아래와 같이 정의되어 있습니다.
    - public boolean onDoubleTap(MotionEvent e)
        두 번 터치입니다. onDoubleTap은 두 번 터치하면 이벤트가 더 이상 발생 되지 않는다.
    - public boolean onDoubleTapEvent(MotionEvent e)
        DOWN, MOVE, UP 이벤트를 모두 포함 합니다. 
    - public boolean onDown(MotionEvent e)
        터치하려고 손을 대기만 해도 발생되는 이벤트, 모든 제스쳐의 시작
    - public boolean onFling(MotionEvent e1, MotionEvent e2, float vX, float vY)
        onScroll에서 끝을 살짝 튕기는 동작에서 발생하는 이벤트
    - public void onLongPress(MotionEvent e)
        스크롤 시에 발생하는 이벤트
    - public boolean onScroll(MotionEvent e1, MotionEvent e2, float dX, float dY)
        길게 눌렀을 때 발생 하는 이벤트
    - public void onShowPress(MotionEvent e)
        onLongPress보다는 좀 더 짧은 시간동안 누르고 있으면 발생 하는 이벤트
    - public boolean onSingleTapConfirmed(MotionEvent e)
        한 번 터치 했을 때 발생하는 이벤트
    - public boolean onSingleTapUp(MotionEvent e) 
        한 번 터치 하고 다음에 다시 터치 이벤트가 들어오지 않았을 때, 한 번 터치가 확실 하다고 확인 시켜주는 이벤트

1. 아주 살짝 터치
    onDown : ACTION_DOWN
    onSingleTapUp : ACTION_UP
    onSingleTapConfirmed : ACTION_DOWN
일단 손을 대면 무조건 onDown 이벤트 발생입니다.
살짝 터치를 하게 되면 보통 30~60ms 정도 후에 손이 떨어지게 됩니다.
손이 떨어 지면 onSingleTapUp 이벤트가 발생하며, onDown이벤트 발생 후 약 300ms 안에 다시 onDown 이벤트가 발생 하지 않는다면 onSingleTapConfirmed 이벤트가 발생하여 확실히 한 번 터치 되었다는 이벤트를 발생 시킵니다.

2. 살짝 터치
    onDown : ACTION_DOWN
    onShowPress : ACTION_DOWN
    onSingleTapUp : ACTION_UP
    onSingleTapConfirmed : ACTION_DOWN
역시나 onDown 이벤트 부터 시작입니다.
1번 보다는 살짝 길게, 약 90~100ms 정도 터치되면 onShowPress 이벤트가 발생합니다. 172ms 이후에 손을 떼었으며, 역시나 300ms 정도 지나면 onSingleTapConfirmed 이벤트가 발생 됩니다.

3. 약간 길게 터치
    onDown : ACTION_DOWN
    onShowPress : ACTION_DOWN
    onSingleTapUp : ACTION_UP
2번보다 좀 더 길지만, LongPress는 아닌 상황입니다.
역시 이 때도 약 100ms 정도에 onShowPress 이벤트가 발생하긴 하지만 300ms 이후에 손을 떼었기 때문에 onSingleTapConfirmed 이벤트가 먹히는 현상이 일어납니다.

4. 아주 길게 터치
    onDown : ACTION_DOWN
    onShowPress : ACTION_DOWN
    onLongPress : ACTION_DOWN
LongPress가 발생 하는 상황입니다.
100ms 정도에 onShowPress 이벤트가 발생 하며, 약 590~600ms 정도에 onLongPress 이벤트가 발생 합니다.
이때 onSingleTapUp 이벤트는 발생 하지 않습니다.
두 번 터치 하는 경우에는 이벤트가 두 가지이기 때문에, 두 가지 조합의 경우 모두 살펴 보겠습니다.

5. 두 번 터치 (onDoubleTap)
    onDown : ACTION_DOWN
    onSingleTapUp : ACTION_UP
    onDoubleTap : ACTION_DOWN
    onDown : ACTION_DOWN (지연 될 수 있음)
먼저 onSingleTapUp 이벤트가 발생 합니다.
그리고 onSingleTapConfirmed 가 발생 하기 전에 다시 onDown 이벤트가 들어오게 되면 onDoubleTap 이벤트가 발생 합니다.
참고로 두번째 들어오는 onDown 이벤트는 onDoubleTap 이벤트보다 늦게 들어 올 수 있습니다.
(항상 같이 들어 오는게 아니라 onDoubleTap이 먼저 발생 합니다.)

6. 두 번 터치 (onDoubleTapEvent)
    onDown : ACTION_DOWN
    onSingleTapUp : ACTION_UP
    onDoubleTapEvent : ACTION_DOWN
    onDown : ACTION_DOWN (지연 될 수 있음)
    onDoubleTapEvent : ACTION_UP
onDoubleTap 이벤트와의 차이는 DOWN, MOVE, UP 이벤트까지 모두 캐치된다는 점이며, 마지막에 onDoubleTapEvent에 UP 액션이 들어오는 것을 확인 할 수 있습니다.
(위의 경우, 190ms 이후에 두번째 터치에서 손이 떨어졌다는 것을 확인 할 수 있습니다.)

7. 두 번 터치 (onDoubleTap + onDoubleTapEvent)
    onDown : ACTION_DOWN
    onSingleTapUp : ACTION_UP
    onDoubleTap : ACTION_DOWN
    onDoubleTapEvent : ACTION_DOWN (지연 될 수 있음)
    onDown : ACTION_DOWN (지연 될 수 있음)
    onDoubleTapEvent : ACTION_UP
같이 사용 하게 되면 onDoubleTap, onDoubleTapEvent 이벤트 둘 다 발생하며, 항상 onDoubleTap 이벤트가 먼저 발생 하게 됩니다. (결과적으로 onDoubleTap - onDoubleTapEvent - onDown 순서로 발생 합니다.)

8. 두 번 터치, 두 번째 터치시 스크롤 (onDoubleTapEvent)
    onDown : ACTION_DOWN
    onSingleTapUp : ACTION_UP
    onDoubleTapEvent : ACTION_DOWN
    onDown : ACTION_DOWN (지연 될 수 있음)
    onDoubleTapEvent : ACTION_MOVE
    onShowPress : ACTION_DOWN
    ...
    onDoubleTapEvent : ACTION_MOVE
    ...
    onLongPress : ACTION_DOWN
    onDoubleTapEvent : ACTION_UP
평소에 절대 나올법한 제스쳐지만 onDoubleTapEvent의 특성을 살펴보기 위한 제스쳐 입니다.
두 번째 onDown 이벤트 이후에 MOVE 이벤트가 들어 오는 것을 확인 할 수 있으며, 한가지 특이한 점은 계속 스크롤 되지 않고 onLongPress 이벤트가 발생하면 끝난다는 점입니다.
손을 뗄 수 밖에 없는 상황이 오게 되죠.
위에서 보시다 시피, 조금 길게 눌러짐에 따라 onShowPressonLongPress가 도중에 발생 할 수도 있습니다.

9. 스크롤
    onDown : ACTION_DOWN
    onScroll : ACTION_DOWN, ACTION_MOVE   
스크롤 이벤트는 간단 합니다.
최소 30ms 이후 부터는 onScroll 이벤트가 발생 할 수 있으며, 플링시키지 않고 살며시 손을 떼면 끝까지 onScroll 이벤트만 연속으로 발생 합니다.

10. 플링
    onDown : ACTION_DOWN
    onScroll : ACTION_DOWN, ACTION_MOVE 
    ...
    onFling : ACTION_DOWN, ACTION_UP
마지막에 손가락을 슬며시 튕기는 플링 동작입니다. 스크롤 이벤트와 비슷하지만, 마지막에 UP 액션과 함께 onFling 이벤트가 동작합니다. 스크롤과 플링 제스쳐 모두 시간에 따라 onShowPress 이벤트가 발생 할 수 있습니다.

지금까지 Android에서 기본적으로 제공하는 GestureDetector에 대해서 간략하게 알아봤다. GestureDetector가 모든 사용자들의 제스쳐를 판별할 수는 없다. 어플리케이션의 성격과 기능에 따라 점더 섬세하고 세세한 GestureDetector가 필요할 수도 있다.