스타일러스는 생산성과 창의성이 뛰어난 도구가 될 수 있습니다. 하지만 사용자는 스타일러스를 사용하여 앱에서 그리거나 쓰거나 상호작용할 때 손바닥으로 화면을 터치하기도 합니다. 시스템이 이러한 이벤트를 의도치 않은 손바닥 터치로 인식하여 무시하기 전에 터치 이벤트가 앱에 보고될 수 있습니다.
권장사항
앱은 관련 없는 터치 이벤트를 식별하여 무시해야 합니다. Jetpack
Compose에서는 기본 Android MotionEvent에서
PointerEvent 액세스할 수 있습니다. 동작이 중지되어야 하고 롤백해야 할 수 있음을 나타내는 MotionEvent에 ACTION_CANCEL를 확인합니다. Android 13 (API 수준 33) 이상에서는 FLAG_CANCELED 플래그
를 ACTION_CANCEL 및 ACTION_POINTER_UP 이벤트에서 확인합니다. 이 플래그는 손바닥 터치와 같이 터치가 의도치 않았다는 강력한 신호를 제공합니다.
재료
Modifier.pointerInput(): 포인터 입력을 처리하는 데 사용되는 Compose 수정자입니다.PointerEvent: 하나 이상의 변경사항이 포함된 Compose의 포인터 이벤트를 나타냅니다.PointerEvent.motionEvent: 기본 AndroidMotionEvent(nullable)에 액세스할 수 있는 확장 속성입니다.MotionEvent: 터치 및 이동 이벤트를 나타냅니다. 이벤트를 무시할지 결정하는 데 필요한 정보가 포함되어 있습니다.ACTION_CANCEL: 동작이 취소되었음을 나타내는MotionEvent상수입니다. 동작이 중지되어야 하고 롤백해야 할 수 있습니다.ACTION_POINTER_UP: 첫 번째 포인터 이외의 포인터가 소실되었음을, 즉 기기 화면과의 접촉을 포기했음을 나타내는MotionEvent상수입니다.FLAG_CANCELED: 포인터가 소실되어 의도치 않은 터치 이벤트가 발생했음을 나타내는MotionEvent상수입니다. Android 13 (API 수준 33) 및 이후 버전의ACTION_POINTER_UP과ACTION_CANCEL이벤트에 추가되었습니다.
단계
앱에 전달된 MotionEvent 객체를 검사합니다. MotionEvent API를 사용하여 이벤트 특성을 판단합니다.
- 단일 포인터 이벤트 : 동작이 중지되어야 함을 나타내는
ACTION_CANCEL을 확인합니다. Android 13 이상에서는FLAG_CANCELED도 확인하여 터치가 의도치 않았음을 확인합니다. - 멀티 포인터 이벤트 : Android 13 이상에서는
ACTION_POINTER_UP및FLAG_CANCELED를 확인하여 의도치 않은 터치를 식별합니다.
동작을 중지하고 임시 변경사항을 롤백하여 이러한 이벤트에 응답합니다.
1. 모션 이벤트 객체 획득
Modifier.pointerInput을 사용하여 컴포저블에서 포인터 입력을 처리합니다. 포인터 입력 범위 내에서 awaitPointerEventScope 및 awaitPointerEvent를 사용하여 이벤트를 수신하고 기본 Android MotionEvent를 motionEvent 속성을 사용하여 검색합니다.
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_CANCEL에 MotionEvent를 확인합니다. Android 13 이상에서는 FLAG_CANCELED에 ACTION_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 수준의 단일 포인터 이벤트에서 손바닥 터치를 식별하고 무시할 수 있습니다.
추가 리소스
자세한 내용은 다음을 참고하세요.
- Android 13 기능 및 API: 손바닥 움직임 무시 개선
- 개발자 가이드
- 고급 스타일러스 기능
- 손바닥 움직임 무시 섹션: 대형 화면에서의 입력 호환성
- Codelab: Android 앱에서 스타일러스 지원 개선