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_CANCEL i ACTION_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 obiektuMotionEventAndroida (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:MotionEventstała, która wskazuje, że gest został anulowany; gest powinien zostać przerwany i może wymagać cofnięcia.ACTION_POINTER_UP:MotionEventstała, która wskazuje, że wskaźnik inny niż pierwszy został podniesiony (czyli stracił kontakt z ekranem urządzenia).FLAG_CANCELED:MotionEventstała wskazująca, że podniesienie wskaźnika spowodowało niezamierzone zdarzenie dotknięcia. Dodane do zdarzeńACTION_POINTER_UPiACTION_CANCELna 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ę ikonaFLAG_CANCELED, aby potwierdzić, że dotknięcie było przypadkowe. - Zdarzenia wielopunktowe – na urządzeniach z Androidem 13 lub nowszym sprawdzaj symbole
ACTION_POINTER_UPiFLAG_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 awaitPointerEventScope i awaitPointerEvent, 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:
- Funkcje i interfejsy API Androida 13 – ulepszone odrzucanie dotyku dłoni
- Przewodniki dla programistów
- Zaawansowane funkcje rysika
- Sekcja Odrzucanie dotyku dłoni w artykule Zgodność danych wejściowych na dużych ekranach
- Ćwiczenie z programowania – Ulepszanie obsługi rysika w aplikacji na Androida