스타일러스 손바닥 움직임 무시

별 5개 평점 아이콘

스타일러스는 생산성과 창의성이 뛰어난 도구가 될 수 있습니다. 하지만 사용자는 스타일러스를 사용하여 앱에서 그리거나 쓰거나 상호작용할 때 손바닥으로 화면을 터치하기도 합니다. 시스템이 이러한 이벤트를 의도치 않은 손바닥 터치로 인식하여 무시하기 전에 터치 이벤트가 앱에 보고될 수 있습니다.

권장사항

앱은 관련 없는 터치 이벤트를 식별하여 무시해야 합니다. Jetpack Compose에서는 기본 Android MotionEvent에서 PointerEvent 액세스할 수 있습니다. 동작이 중지되어야 하고 롤백해야 할 수 있음을 나타내는 MotionEventACTION_CANCEL를 확인합니다. Android 13 (API 수준 33) 이상에서는 FLAG_CANCELED 플래그 를 ACTION_CANCELACTION_POINTER_UP 이벤트에서 확인합니다. 이 플래그는 손바닥 터치와 같이 터치가 의도치 않았다는 강력한 신호를 제공합니다.

재료

  • Modifier.pointerInput(): 포인터 입력을 처리하는 데 사용되는 Compose 수정자입니다.
  • PointerEvent: 하나 이상의 변경사항이 포함된 Compose의 포인터 이벤트를 나타냅니다.
  • PointerEvent.motionEvent: 기본 Android MotionEvent (nullable)에 액세스할 수 있는 확장 속성입니다.
  • MotionEvent: 터치 및 이동 이벤트를 나타냅니다. 이벤트를 무시할지 결정하는 데 필요한 정보가 포함되어 있습니다.
  • ACTION_CANCEL: 동작이 취소되었음을 나타내는 MotionEvent 상수입니다. 동작이 중지되어야 하고 롤백해야 할 수 있습니다.
  • ACTION_POINTER_UP: 첫 번째 포인터 이외의 포인터가 소실되었음을, 즉 기기 화면과의 접촉을 포기했음을 나타내는 MotionEvent 상수입니다.
  • FLAG_CANCELED: 포인터가 소실되어 의도치 않은 터치 이벤트가 발생했음을 나타내는 MotionEvent 상수입니다. Android 13 (API 수준 33) 및 이후 버전의 ACTION_POINTER_UPACTION_CANCEL 이벤트에 추가되었습니다.

단계

앱에 전달된 MotionEvent 객체를 검사합니다. MotionEvent API를 사용하여 이벤트 특성을 판단합니다.

  • 단일 포인터 이벤트 : 동작이 중지되어야 함을 나타내는 ACTION_CANCEL을 확인합니다. Android 13 이상에서는 FLAG_CANCELED도 확인하여 터치가 의도치 않았음을 확인합니다.
  • 멀티 포인터 이벤트 : Android 13 이상에서는 ACTION_POINTER_UPFLAG_CANCELED를 확인하여 의도치 않은 터치를 식별합니다.

동작을 중지하고 임시 변경사항을 롤백하여 이러한 이벤트에 응답합니다.

1. 모션 이벤트 객체 획득

Modifier.pointerInput을 사용하여 컴포저블에서 포인터 입력을 처리합니다. 포인터 입력 범위 내에서 awaitPointerEventScopeawaitPointerEvent를 사용하여 이벤트를 수신하고 기본 Android MotionEventmotionEvent 속성을 사용하여 검색합니다.

import androidx.compose.ui.input.pointer.pointerInput
    Box(
        modifier = Modifier
            .fillMaxSize()
            .pointerInput(Unit) {
                awaitPointerEventScope {
                    while (true) {
                        val event = awaitPointerEvent()
                        val motionEvent = event.motionEvent
                        if (motionEvent != null) {
                            // Process motion event.
                        }
                    }
                }
            }
    )

2. 이벤트 작업 및 플래그 확인

모든 API 수준에서 단일 포인터 이벤트를 나타내는 ACTION_CANCELMotionEvent를 확인합니다. Android 13 이상에서는 FLAG_CANCELEDACTION_POINTER_UP을 확인합니다.

import androidx.compose.ui.input.pointer.pointerInput
    Box(
        modifier = Modifier
            .fillMaxSize()
            .pointerInput(Unit) {
                awaitPointerEventScope {
                    while (true) {
                        val event = awaitPointerEvent()
                        val motionEvent = event.motionEvent ?: continue

                        when (motionEvent.actionMasked) {
                            MotionEvent.ACTION_CANCEL -> {
                                // Process canceled single-pointer motion event for all SDK versions.
                            }
                            MotionEvent.ACTION_POINTER_UP -> {
                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
                                    (motionEvent.flags and MotionEvent.FLAG_CANCELED) == MotionEvent.FLAG_CANCELED
                                ) {
                                    // Process canceled multi-pointer motion event for Android 13 and higher.
                                }
                            }
                        }
                    }
                }
            }
    )

3. 동작 실행취소

손바닥 터치를 식별한 후에는 동작이 화면에 미치는 효과를 실행취소할 수 있습니다.

손바닥 터치와 같은 의도하지 않은 입력이 실행취소될 수 있도록 앱에서는 사용자 작업 기록을 유지해야 합니다. 예를 보려면 기본 그리기 앱 구현을(를) Android 앱에서 스타일러스 지원 개선 Codelab에서 참고하세요.

결과

이제 앱은 Android 13 이상 API 수준의 멀티 포인터 이벤트와 모든 API 수준의 단일 포인터 이벤트에서 손바닥 터치를 식별하고 무시할 수 있습니다.

추가 리소스

자세한 내용은 다음을 참고하세요.