깨알 개념/Android

[Android] Pointer input - AwaitPointerEventScope()의 메소드들

interfacer_han 2025. 2. 8. 16:50

#1 개요

#1-1 이전 게시글

 

[Android] Pointer input - PointerInputChange, PointerEvent

#1 개요 동작 이해하기  |  Jetpack Compose  |  Android Developers이 페이지는 Cloud Translation API를 통해 번역되었습니다. 동작 이해하기 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저

kenel.tistory.com

위 게시글에서 AwaitPointerEventScope()의 가장 대표적인 메소드인 awaitPointerEvent()에 대해 간단히 설명했다. 본 게시글에선 awaitPointerEvent()를 제외한 나머지 메소드들을 설명한다.
 

#1-2 공식 문서

 

AwaitPointerEventScope  |  Android Developers

androidx.appsearch.builtintypes.properties

developer.android.com

이 아래 내용부턴, 위의 공식 문서를 기반으로 작성했다. 영어 능력자라면 내 글보다 위의 공식 문서를 읽는 편이 훨씬 좋을 것이다.
 

#2 용어 정리

#2-1 취소 (Cancellation)

Pointer의 동작이 끝까지 수행되지 않고 중간에 실패함을 의미. 스마트폰 화면 회전, 갑자기 홈 화면으로 나가짐 등이 원인. 본 게시글에선 특별히 주황색 글씨로 표시하겠다.
 

#2-2 터치 민감도 (Touch Slop)

Pointer를 얼마의 거리만큼 움직어야 '드래그'로 인식하는 지의 기준 값 또는 그렇게 해서 인식된 드래그. 본 게시글에선 특별히 보라색 글씨로 표기하겠다.

 

#2-3 소비 (Consume)

 

[Android] Pointer input - PointerInputChange, PointerEvent

#1 개요 동작 이해하기 | Jetpack Compose | Android Developers이 페이지는 Cloud Translation API를 통해 번역되었습니다. 동작 이해하기 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고

kenel.tistory.com

위 게시글 참조. 본 게시글에선 특별히 파란색 글씨로 표기하겠다.

 

#3 메소드 목록 - 기본

#3-1 awaitFirstDown()

suspend fun AwaitPointerEventScope.awaitFirstDown(
    requireUnconsumed: Boolean = true,
    pass: PointerEventPass = PointerEventPass.Main
): PointerInputChange

설명
'첫번째' 터치를 기다림. '첫번째'라는 말은 어떤 맥락으로 사용되었는가? 예를 들어, 스마트폰 사용자가 화면에 손가락을 대고 이리저리 드래그했다가 떼었다고 치자. 이 경우 '첫번째' 터치는 화면에 손가락을 댄 순간의 터치를 의미한다. 함수명에 있는 'down'이 이 의미다. 화면에 손가락을 내려(down)놓은 순간이라는 늬앙스다. requireUnconsumed를 false로 명시하면, 이미 소비된 '첫번째' 터치도 감지한다.

반환

'첫번째' 터치에 해당하는 PointerInputChange 반환.

 

#3-2 awaitLongPressOrCancellation()

suspend fun AwaitPointerEventScope.awaitLongPressOrCancellation(
    pointerId: PointerId
): PointerInputChange?

설명
꾹 누르는 클릭 이벤트를 기다림.

반환

꾹 누르는 클릭 이벤트에 해당하는 PointerInputChange를 반환한다. 취소되면 대신 null을 반환한다.

 

#3-3 waitForUpOrCancellation()

suspend fun AwaitPointerEventScope.waitForUpOrCancellation(
    pass: PointerEventPass = PointerEventPass.Main
): PointerInputChange?

설명
손가락이 화면에서 떼어질(Up) 것을 기다림. awaitFirstDown()의 반대다.

반환

정상적으로 손가락이 화면에서 떼어졌다면 해당되는 PointerInputChange가 반환되고, 취소되면 대신 null을 반환.

 

#4 메소드 목록 - 드래그 관련

#4-1 drag()

suspend fun AwaitPointerEventScope.drag(
    pointerId: PointerId,
    onDrag: (PointerInputChange) -> Unit
): Boolean

설명
특정 포인터의 드래그를 추적. 특정 포인터가 드래그를 수행할 때마다 프로그래머가 구현해 넣은 onDrag() 함수가 실행됨. 터치 민감도를 신경 쓰지 않으므로, 아주 살짝만 움직여도 감지함.

 

반환
null을 반환하지 않으며, 반드시 PointerInputChange 객체를 반환.

 

용례

modifier.pointerInput(Unit) {
    awaitPointerEventScope {
        val down = awaitFirstDown() // '첫번째' 터치 감지
        drag(down.id) { change -> 
            println("Dragging: ${change.position}") // 현재 터치 좌표 출력
        }
    }
}

 

#4-2 verticalDrag()

suspend fun AwaitPointerEventScope.verticalDrag(
    pointerId: PointerId,
    onDrag: (PointerInputChange) -> Unit
): Boolean

설명
수직 드래그만을 감지한다는 점을 제외하면 drag()와 동일하다.

 

#4-3 horizontalDrag()

suspend fun AwaitPointerEventScope.horizontalDrag(
    pointerId: PointerId,
    onDrag: (PointerInputChange) -> Unit
): Boolean

설명
수평 드래그만을 감지한다는 점을 제외하면 drag()와 동일하다.

 

#4-4 awaitDragOrCancellation()

suspend fun AwaitPointerEventScope.awaitDragOrCancellation(pointerId: PointerId): PointerInputChange?

설명
특정 포인터의 '드래그가 시작됨'를 감지. drag()가 드래그가 진행되는 중인 포인터로부터 실시간 위치를 추적해 전달받는 용도라면, 본 함수인 awaitDragOrCancellation()은 그저 드래그가 시작되었음을 감지함. 따라서 drag()처럼 onDrag() 함수 따위를 보유하지 않음. 터치 민감도를 신경 쓰지 않으므로, 아주 살짝만 움직여도 감지함.

반환

드래그가 시작되면 해당 포인터의 PointerInputChange 반환. 취소되면 대신 null 반환.

 

용례

modifier.pointerInput(Unit) {
    awaitPointerEventScope {
        val down = awaitFirstDown() // 첫 번째 터치 감지
        val drag = awaitDragOrCancellation(down.id) // 드래그 시작 감지 (취소될 수도 있음)

        if (drag != null) {
            println("드래그 시작됨: ${drag.position}")
        } else {
            println("드래그가 취소됨") // 터치가 중간에 취소되었을 경우
        }
    }
}

 

#4-5 awaitVerticalDragOrCancellation()

suspend fun AwaitPointerEventScope.awaitVerticalDragOrCancellation(
    pointerId: PointerId
): PointerInputChange?

설명
수직 드래그만을 감지한다는 점을 제외하면 awaitDragOrCancellation()와 동일하다.

 

#4-6 awaitHorizontalDragOrCancellation()

suspend fun AwaitPointerEventScope.awaitHorizontalDragOrCancellation(
    pointerId: PointerId
): PointerInputChange?

설명
수평 드래그만을 감지한다는 점을 제외하면 awaitDragOrCancellation() 와 동일하다.

 

#5 메소드 목록 - 터치 민감도 관련

#5-1 awaitTouchSlopOrCancellation()

suspend fun AwaitPointerEventScope.awaitTouchSlopOrCancellation(
    pointerId: PointerId,
    onTouchSlopReached: (change: PointerInputChange, overSlop: Offset) -> Unit
): PointerInputChange?

설명
프로그래머가 명시한 터치 민감도를 초과해야 '드래그'라고 인식한다는 점을 제외하면, awaitDragOrCancellation()와 거의 동일하다. 또, awaitDragOrCancellation()에는 없는 (사용자가 특정 터치 민감도를 초과했을 때 호출될) 콜백 함수도 존재한다. 

 

#5-2 awaitVerticalTouchSlopOrCancellation()

suspend fun AwaitPointerEventScope.awaitVerticalTouchSlopOrCancellation(
    pointerId: PointerId,
    onTouchSlopReached: (change: PointerInputChange, overSlop: Float) -> Unit
): PointerInputChange?

설명
수직 드래그만을 감지한다는 점을 제외하면 awaitTouchSlopOrCancellation()와 동일하다.

 

#5-3 awaitHorizontalTouchSlopOrCancellation()

suspend fun AwaitPointerEventScope.awaitHorizontalTouchSlopOrCancellation(
    pointerId: PointerId,
    onTouchSlopReached: (change: PointerInputChange, overSlop: Float) -> Unit
): PointerInputChange?

설명
수평 드래그만을 감지한다는 점을 제외하면 awaitTouchSlopOrCancellation()와 동일하다.