Z tej lekcji dowiesz się, jak śledzić ruch w zdarzeniach dotknięcia.
Nowy
onTouchEvent()
jest wywoływane razem z
ACTION_MOVE
zdarzenie
za każdym razem, gdy zmieni się bieżąca pozycja kontaktu dotykowego, jego nacisk lub rozmiar. Jako
opisane w artykule Wykrywanie typowych gestów,
te zdarzenia są rejestrowane w
MotionEvent
parametr
onTouchEvent()
.
Używanie palców nie zawsze jest najdokładniejszą formą interakcji, Wykrywanie zdarzeń dotknięcia często opiera się bardziej na ruchu niż na prostym kontakcie. Aby ułatwić aplikacjom rozróżnianie gestów związanych z ruchem (np. przesuwania palcem) niezawierających ruchu (np. jedno kliknięcie) upływu ekranu. Upływ dotknięcia odnosi się do odległości w pikselach, jaką użytkownik może uzyskać po dotknięciu powinien przejść, zanim zostanie zinterpretowany jako gest związany z ruchem. Więcej więcej informacji na ten temat znajdziesz w artykule Zarządzanie zdarzeniami dotknięcia w ViewGroup.
Istnieje kilka sposobów śledzenia ruchu za pomocą gestów w zależności od do konkretnych potrzeb aplikacji. Przykłady:
- Początkowa i końcowa pozycja wskaźnika, np. przesunięcie kursora na ekranie. od punktu A do punktu B.
- Kierunek, w którym porusza się wskaźnik, określony za pomocą osi X i Y .
- Historia. Rozmiar historii gestu możesz sprawdzić, wywołując
MotionEvent
metodagetHistorySize()
Następnie można sprawdzić położenie, rozmiar, czas i siłę każdej z reklam wydarzeń historycznych za pomocą funkcji zdarzenia ruchugetHistorical<Value>
. Historia jest przydatna podczas renderowania śladu palca użytkownika, takiego jak jak w przypadku rysowania dotykiem. Więcej informacji znajdziesz w dokumentacjiMotionEvent
. - Szybkość, z jaką wskaźnik porusza się po ekranie dotykowym.
Zapoznaj się z tymi powiązanymi materiałami:
Prędkość na torze
Możesz używać gestów opartych na ruchu, które zależą od odległości lub kierunku
przesuwa się wskaźnik. Jednak prędkość jest często decydującym czynnikiem w śledzeniu
właściwości gestu lub podjęcie decyzji o jego użyciu. Aby zrobić
obliczanie szybkości, Android zapewnia
VelocityTracker
.
Funkcja VelocityTracker
pomaga śledzić częstotliwość zdarzeń dotknięcia. To jest przydatne
dla gestów, których szybkość jest częścią kryteriów gestu, na przykład
romans.
Oto przykład, który ilustruje przeznaczenie metod w
Interfejs API VelocityTracker
:
Kotlin
private const val DEBUG_TAG = "Velocity" class MainActivity : Activity() { private var mVelocityTracker: VelocityTracker? = null override fun onTouchEvent(event: MotionEvent): Boolean { when (event.actionMasked) { MotionEvent.ACTION_DOWN -> { // Reset the velocity tracker back to its initial state. mVelocityTracker?.clear() // If necessary, retrieve a new VelocityTracker object to watch // the velocity of a motion. mVelocityTracker = mVelocityTracker ?: VelocityTracker.obtain() // Add a user's movement to the tracker. mVelocityTracker?.addMovement(event) } MotionEvent.ACTION_MOVE -> { mVelocityTracker?.apply { val pointerId: Int = event.getPointerId(event.actionIndex) addMovement(event) // When you want to determine the velocity, call // computeCurrentVelocity(). Then, call getXVelocity() and // getYVelocity() to retrieve the velocity for each pointer // ID. computeCurrentVelocity(1000) // Log velocity of pixels per second. It's best practice to // use VelocityTrackerCompat where possible. Log.d("", "X velocity: ${getXVelocity(pointerId)}") Log.d("", "Y velocity: ${getYVelocity(pointerId)}") } } MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { // Return a VelocityTracker object back to be re-used by others. mVelocityTracker?.recycle() mVelocityTracker = null } } return true } }
Java
public class MainActivity extends Activity { private static final String DEBUG_TAG = "Velocity"; ... private VelocityTracker mVelocityTracker = null; @Override public boolean onTouchEvent(MotionEvent event) { int index = event.getActionIndex(); int action = event.getActionMasked(); int pointerId = event.getPointerId(index); switch(action) { case MotionEvent.ACTION_DOWN: if(mVelocityTracker == null) { // Retrieve a new VelocityTracker object to watch the // velocity of a motion. mVelocityTracker = VelocityTracker.obtain(); } else { // Reset the velocity tracker back to its initial state. mVelocityTracker.clear(); } // Add a user's movement to the tracker. mVelocityTracker.addMovement(event); break; case MotionEvent.ACTION_MOVE: mVelocityTracker.addMovement(event); // When you want to determine the velocity, call // computeCurrentVelocity(). Then call getXVelocity() and // getYVelocity() to retrieve the velocity for each pointer ID. mVelocityTracker.computeCurrentVelocity(1000); // Log velocity of pixels per second. It's best practice to use // VelocityTrackerCompat where possible. Log.d("", "X velocity: " + mVelocityTracker.getXVelocity(pointerId)); Log.d("", "Y velocity: " + mVelocityTracker.getYVelocity(pointerId)); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: // Return a VelocityTracker object back to be re-used by others. mVelocityTracker.recycle(); break; } return true; } }
Używaj przechwytywania wskaźnika
Niektóre aplikacje, takie jak gry, klienty pulpitu zdalnego i wirtualizacji, nad kontrolowaniem kursora myszy. Przechwytywanie wskaźnika to funkcja jest dostępna w Androidzie 8.0 (poziom interfejsu API 26) i nowszych. Zapewnia to kontrolę wyświetlanie wszystkich zdarzeń myszy w zaznaczonym widoku aplikacji.
Poproś o zdjęcie wskaźnika
Widok w aplikacji może poprosić o przechwycenie wskaźnika tylko wtedy, gdy hierarchia widoków
jest zaznaczony. Z tego powodu poproś o przechwycenie wskaźnika, gdy
określonego działania użytkownika w widoku danych, np. podczas
onClick()
lub w elemencie
onWindowFocusChanged()
modułu obsługi zdarzeń
Twojej aktywności.
Aby poprosić o przechwycenie wskaźnika, wywołaj funkcję
requestPointerCapture()
dla widoku. Poniższy przykładowy kod pokazuje, jak poprosić o wskaźnik
Przechwytuje się, gdy użytkownik kliknie film.
Kotlin
fun onClick(view: View) { view.requestPointerCapture() }
Java
@Override public void onClick(View view) { view.requestPointerCapture(); }
Gdy żądanie przechwycenia wskaźnika zostanie zrealizowane, Android wywołuje
onPointerCaptureChange(true)
System dostarcza zdarzenia myszy do aktywnego widoku aplikacji,
znajduje się w tej samej hierarchii widoków co widok, z którego przechwycono obraz. Inny powód
do czasu udostępnienia funkcji przechwytywania aplikacji nie odbierają zdarzeń myszy, w tym
ACTION_OUTSIDE
zdarzeń. Android dostarcza zdarzenia wskaźnika ze źródeł innych niż mysz,
ale wskaźnik myszy nie jest już widoczny.
Obsługa przechwyconych zdarzeń wskaźnika
Gdy widok zostanie przechwycony wskaźnikiem, Android przesyła zdarzeń myszy. Zawężony widok może obsługiwać zdarzenia, wykonując jedną z następujące zadania:
- Jeśli korzystasz z widoku niestandardowego, zastąp
onCapturedPointerEvent(MotionEvent)
- W przeciwnym razie zarejestruj
OnCapturedPointerListener
Poniższy przykładowy kod pokazuje, jak zaimplementować
onCapturedPointerEvent(MotionEvent)
:
Kotlin
override fun onCapturedPointerEvent(motionEvent: MotionEvent): Boolean { // Get the coordinates required by your app. val verticalOffset: Float = motionEvent.y // Use the coordinates to update your view and return true if the event is // successfully processed. return true }
Java
@Override public boolean onCapturedPointerEvent(MotionEvent motionEvent) { // Get the coordinates required by your app. float verticalOffset = motionEvent.getY(); // Use the coordinates to update your view and return true if the event is // successfully processed. return true; }
Poniższy przykładowy kod pokazuje, jak zarejestrować
OnCapturedPointerListener
:
Kotlin
myView.setOnCapturedPointerListener { view, motionEvent -> // Get the coordinates required by your app. val horizontalOffset: Float = motionEvent.x // Use the coordinates to update your view and return true if the event is // successfully processed. true }
Java
myView.setOnCapturedPointerListener(new View.OnCapturedPointerListener() { @Override public boolean onCapturedPointer (View view, MotionEvent motionEvent) { // Get the coordinates required by your app. float horizontalOffset = motionEvent.getX(); // Use the coordinates to update your view and return true if the event is // successfully processed. return true; } });
Niezależnie od tego, czy korzystasz z widoku niestandardowego, czy rejestrujesz detektor, widok otrzymuje
MotionEvent
ze współrzędnymi wskaźnika, które określają ruchy względne, np. X
lub delta Y, podobnie jak współrzędne podawane przez kulkę. Dostępne opcje
pobierz współrzędne za pomocą
getX()
i
getY()
Zwolnij zapis wskaźnika
Widok w aplikacji może zwolnić przechwycony wskaźnik przez połączenie
releasePointerCapture()
jak w tym przykładowym kodzie:
Kotlin
override fun onClick(view: View) { view.releasePointerCapture() }
Java
@Override public void onClick(View view) { view.releasePointerCapture(); }
System może odebrać zdjęcie bez Twojej wyraźnej zgody użytkownika.
Wywołuję funkcję releasePointerCapture()
, często dlatego, że hierarchia widoków
który zawiera widok, w którym żądania są przechwytywane.