Questa lezione descrive come tenere traccia dei movimenti negli eventi di contatto.
Un nuovo
onTouchEvent()
viene attivato
Evento ACTION_MOVE
ogni volta che cambiano la posizione corrente del contatto, la pressione o le dimensioni. Come
descritta in Rileva gesti comuni,
questi eventi vengono registrati
MotionEvent
di
onTouchEvent()
,
Poiché il tocco basato sulle dita non è sempre la forma più precisa di interazione, il rilevamento degli eventi di tocco si basa spesso più sul movimento che su un semplice contatto. Per aiutare le app a distinguere tra gesti basati sul movimento (ad esempio lo scorrimento) e gesti che non si muovono (ad esempio un solo tocco), Android include la nozione di dipensione al tocco. Per inclinazione al tocco si intende la distanza in pixel in cui può toccare un utente con un tocco girovagare prima che il gesto venga interpretato come gesto basato sul movimento. Per ulteriori informazioni informazioni su questo argomento, consulta Gestire gli eventi touch in un ViewGroup.
Esistono diversi modi per rilevare il movimento in un gesto, a seconda del le esigenze della tua applicazione. Ecco alcuni esempi:
- La posizione iniziale e finale di un puntatore, ad esempio lo spostamento di un dal punto A al punto B.
- La direzione in cui si sposta il puntatore, come stabilito da X e Y coordinate.
- Cronologia. Puoi conoscere le dimensioni della cronologia di un gesto chiamando il
MotionEvent
metodogetHistorySize()
Puoi quindi ottenere le posizioni, le dimensioni, il tempo e le pressioni di ciascuno eventi storici utilizzando la proprietàgetHistorical<Value>
di machine learning. La cronologia è utile quando si esegue il rendering di una scia del dito dell'utente, come per il disegno al tocco. Per informazioni dettagliate, consulta il riferimento diMotionEvent
. - La velocità del puntatore mentre si sposta sul touchscreen.
Consulta le seguenti risorse correlate:
- Panoramica degli eventi di input
- Panoramica dei sensori
- Rendere interattiva una visualizzazione personalizzata
Monitora la velocità
Puoi avere un gesto basato sul movimento basato sulla distanza o sulla direzione
il puntatore si sposta. Tuttavia, la velocità è spesso un fattore determinante nel monitoraggio
le caratteristiche di un gesto o la decisione
dell'esecuzione o meno del gesto. Per rendere
il calcolo della velocità, Android fornisce
VelocityTracker
.
VelocityTracker
ti aiuta a monitorare la velocità degli eventi touch. È utile
per i gesti in cui la velocità è uno dei criteri dei gesti, ad esempio
un'avventura.
Ecco un esempio che illustra lo scopo dei metodi in
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; } }
Usa acquisizione puntatore
Alcune app, come i giochi, il desktop remoto e i client di virtualizzazione, di non avere più controllo sul puntatore del mouse. L'acquisizione del puntatore è una funzionalità disponibile in Android 8.0 (livello API 26) e versioni successive che offre questo controllo mostrare tutti gli eventi del mouse in una vista mirata nell'app.
Richiedi acquisizione puntatore
Una vista nella tua app può richiedere l'acquisizione del puntatore solo se la gerarchia delle visualizzazioni che
contiene lo stato attivo. Per questo motivo, richiedi l'acquisizione del puntatore quando è presente
un'azione specifica dell'utente sulla vista, ad esempio durante
onClick()
o nel
onWindowFocusChanged()
gestore di eventi della tua attività.
Per richiedere l'acquisizione del puntatore, richiama il metodo
requestPointerCapture()
nella vista. L'esempio di codice seguente mostra come richiedere il puntatore
registrare quando l'utente fa clic su una visualizzazione:
Kotlin
fun onClick(view: View) { view.requestPointerCapture() }
Java
@Override public void onClick(View view) { view.requestPointerCapture(); }
Quando la richiesta di acquisizione del puntatore ha esito positivo, Android chiama
onPointerCaptureChange(true)
Il sistema invia gli eventi del mouse nella visualizzazione con stato attivo dell'app, purché
si trova nella stessa gerarchia di quella che ha richiesto l'acquisizione. Altro
le app smettono di ricevere gli eventi del mouse fino al rilascio dell'acquisizione, inclusi
ACTION_OUTSIDE
eventi. Android invia eventi di puntatore da origini diverse dal mouse
è normale, ma il puntatore del mouse non è più visibile.
Gestire gli eventi del puntatore acquisiti
Una volta che una vista acquisisce correttamente l'acquisizione del puntatore, Android fornisce la del mouse. La vista selezionata può gestire gli eventi eseguendo una delle le seguenti attività:
- Se utilizzi una visualizzazione personalizzata, sostituisci
onCapturedPointerEvent(MotionEvent)
- Altrimenti, registra
OnCapturedPointerListener
Il seguente esempio di codice mostra come implementare
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; }
L'esempio di codice che segue mostra come registrare un
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; } });
Sia che utilizzi una visualizzazione personalizzata sia che registri un listener, la tua visualizzazione riceve un
MotionEvent
con coordinate del puntatore che specificano i movimenti relativi, ad esempio X
o delta Y, simili alle coordinate fornite da un dispositivo trackball. Puoi
recupera le coordinate utilizzando
getX()
e
getY()
.
Acquisizione puntatore di rilascio
La visualizzazione nell'app può rilasciare l'acquisizione del puntatore richiamando
releasePointerCapture()
,
come mostrato nel seguente esempio di codice:
Kotlin
override fun onClick(view: View) { view.releasePointerCapture() }
Java
@Override public void onClick(View view) { view.releasePointerCapture(); }
Il sistema può rimuovere l'acquisizione dalla vista senza che tu debba fare
chiamata releasePointerCapture()
, in genere perché la gerarchia di visualizzazione
che contiene la vista che consente di acquisire le richieste perde lo stato attivo.