Odrzucenie dłoni rysika

Ikona oceny pięciogwiazdkowej

Rysik może być wyjątkowo przydatnym narzędziem, które zwiększa produktywność i kreatywność. Gdy jednak użytkownicy rysują, piszą lub wchodzą w interakcję z aplikacją za pomocą rysika, czasami dotykają ekranu dłonią. Zdarzenie dotknięcia może zostać zgłoszone do aplikacji, zanim system rozpozna i odrzuci je jako przypadkowe dotknięcie dłonią.

Sprawdzone metody

Aplikacja musi identyfikować zbędne zdarzenia dotknięcia i je ignorować. W Jetpack Compose możesz uzyskać dostęp do bazowego Androida MotionEvent z a PointerEvent. Sprawdź MotionEvent pod kątem ACTION_CANCEL, co oznacza, że gest powinien zostać zatrzymany i może wymagać cofnięcia. W Androidzie 13 (poziom interfejsu API 33) i nowszym sprawdź flagę FLAG_CANCELED w zdarzeniach ACTION_CANCEL i ACTION_POINTER_UP, co jest silnym sygnałem, że dotknięcie było niezamierzone, np. dotknięcie dłonią.

Składniki

  • Modifier.pointerInput(): modyfikator Compose używany do przetwarzania danych wejściowych wskaźnika.
  • PointerEvent: reprezentuje zdarzenie wskaźnika w Compose, które zawiera 1 lub więcej zmian.
  • PointerEvent.motionEvent: właściwość rozszerzenia, która zapewnia dostęp do bazowego MotionEvent Androida (może mieć wartość null).
  • MotionEvent: reprezentuje zdarzenia dotknięcia i ruchu. Zawiera informacje niezbędne do określenia, czy zdarzenie należy zignorować.
  • ACTION_CANCEL: stała MotionEvent, która wskazuje, że gest został anulowany; gest powinien zostać zatrzymany i może wymagać cofnięcia.
  • ACTION_POINTER_UP: stała MotionEvent, która wskazuje, że wskaźnik inny niż pierwszy został podniesiony (czyli stracił kontakt z ekranem urządzenia).
  • FLAG_CANCELED: stała MotionEvent, która wskazuje, że podniesienie wskaźnika spowodowało niezamierzone zdarzenie dotknięcia. Dodana do zdarzeń ACTION_POINTER_UP i ACTION_CANCEL w Androidzie 13 (poziom interfejsu API 33) i nowszym.

Kroki

Sprawdź obiekty MotionEvent wysyłane do aplikacji. Użyj interfejsów API MotionEvent, aby określić charakterystykę zdarzenia:

  • Zdarzenia z 1 wskaźnikiem – sprawdź ACTION_CANCEL, co oznacza, że gest powinien zostać zatrzymany. W Androidzie 13 i nowszym sprawdź też FLAG_CANCELED, aby potwierdzić, że dotknięcie było niezamierzone.
  • Zdarzenia z wieloma wskaźnikami – w Androidzie 13 i nowszym sprawdź ACTION_POINTER_UP i FLAG_CANCELED, aby zidentyfikować niezamierzone dotknięcia.

Odpowiedz na te zdarzenia, zatrzymując gest i cofając wszelkie tymczasowe zmiany.

1. Pobierz obiekty zdarzeń ruchu

Użyj Modifier.pointerInput, aby przetwarzać dane wejściowe wskaźnika w komponencie. W zakresie danych wejściowych wskaźnika użyj awaitPointerEventScope i awaitPointerEvent, aby otrzymywać zdarzenia, i pobierz bazowy MotionEvent Androida za pomocą właściwości 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. Określ działanie i flagi zdarzenia

Sprawdź MotionEvent pod kątem ACTION_CANCEL, co oznacza zdarzenie z 1 wskaźnikiem na wszystkich poziomach interfejsu API. W Androidzie 13 i nowszym sprawdź ACTION_POINTER_UP pod kątem FLAG_CANCELED:

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. Cofnij gest

Gdy zidentyfikujesz dotknięcie dłonią, możesz cofnąć efekty gestu na ekranie.

Aplikacja musi przechowywać historię działań użytkownika, aby można było cofnąć niezamierzone dane wejściowe, takie jak dotknięcia dłonią. Przykład znajdziesz w ćwiczeniu Implementowanie podstawowej aplikacji do rysowania w sekcji Ulepszanie obsługi rysika w aplikacji na Androida.

Wyniki

Aplikacja może teraz identyfikować i odrzucać dotknięcia dłonią w przypadku zdarzeń z wieloma wskaźnikami w Androidzie 13 i nowszych wersjach interfejsu API oraz w przypadku zdarzeń z 1 wskaźnikiem na wszystkich poziomach interfejsu API.

Dodatkowe materiały

Więcej informacji znajdziesz w tych materiałach: