Odrzucenie dłoni rysika

Ikona oceny pięciogwiazdkowej

Rysik może być niezwykle przydatnym narzędziem do pracy i tworzenia. Gdy jednak użytkownicy rysują, piszą lub wchodzą w interakcję z aplikacją za pomocą rysika, czasami dotykają ekranu dłonią. Zdarzenie dotyku może zostać zgłoszone do aplikacji, zanim system rozpozna i odrzuci je jako przypadkowy dotyk 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 elementu MotionEvent Androida z poziomu PointerEvent. Sprawdź, czy w MotionEvent znajduje się ACTION_CANCEL, co oznacza, że gest powinien się zatrzymać i może wymagać cofnięcia. Na Androidzie 13 (poziom API 33) i nowszych sprawdzaj flagę FLAG_CANCELED w zdarzeniach ACTION_CANCELACTION_POINTER_UP, która 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 co najmniej 1 zmianę.
  • PointerEvent.motionEvent: właściwość rozszerzenia, która zapewnia dostęp do bazowego obiektu MotionEvent Androida (może mieć wartość null).
  • MotionEvent: reprezentuje zdarzenia dotknięcia i ruchu. Zawiera informacje niezbędne do określenia, czy zdarzenie powinno zostać zignorowane.
  • ACTION_CANCEL: MotionEvent stała, która wskazuje, że gest został anulowany; gest powinien zostać przerwany i może wymagać cofnięcia.
  • ACTION_POINTER_UP: MotionEvent stała, która wskazuje, że wskaźnik inny niż pierwszy został podniesiony (czyli stracił kontakt z ekranem urządzenia).
  • FLAG_CANCELED: MotionEvent stała wskazująca, że podniesienie wskaźnika spowodowało niezamierzone zdarzenie dotknięcia. Dodane do zdarzeń ACTION_POINTER_UPACTION_CANCEL na Androidzie 13 (API na poziomie 33) i nowszym.

Kroki

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

  • Zdarzenia dotyczące jednego wskaźnika – sprawdź wartość ACTION_CANCEL, która wskazuje, że gest powinien się zakończyć. Na urządzeniach z Androidem 13 lub nowszym sprawdź też, czy pojawi się ikona FLAG_CANCELED, aby potwierdzić, że dotknięcie było przypadkowe.
  • Zdarzenia wielopunktowe – na urządzeniach z Androidem 13 lub nowszym sprawdzaj symbole ACTION_POINTER_UPFLAG_CANCELED, aby wykrywać przypadkowe dotknięcia.

Reaguj na te zdarzenia, przerywając gest i cofając wszelkie tymczasowe zmiany.

1. Pozyskiwanie obiektów zdarzeń ruchu

Użyj Modifier.pointerInput, aby przetwarzać dane wejściowe wskaźnika w komponencie. W zakresie danych wejściowych wskaźnika użyj awaitPointerEventScopeawaitPointerEvent, aby odbierać zdarzenia, i pobierz bazowy element 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ślanie działania i flag zdarzenia

Sprawdź MotionEvent dla ACTION_CANCEL, co oznacza zdarzenie z jednym wskaźnikiem na wszystkich poziomach interfejsu API. Na Androidzie 13 lub nowszym sprawdź ACTION_POINTER_UP 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

Po wykryciu dotknięcia 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 sekcji Implementowanie podstawowej aplikacji do rysowania w ćwiczeniu 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 na Androidzie 13 i nowszych oraz zdarzeń z jednym wskaźnikiem na wszystkich poziomach interfejsu API.

Dodatkowe materiały

Więcej informacji znajdziesz w tych artykułach: