Berührungs- und Zeigerbewegungen verfolgen

Schreiben Sie jetzt
Jetpack Compose ist das empfohlene UI-Toolkit für Android. Weitere Informationen zur Verwendung von Berührungen und Eingaben in „Schreiben“
<ph type="x-smartling-placeholder"></ph> Touch-Gesten →

In dieser Lektion wird beschrieben, wie Sie Bewegungen bei Touch-Ereignissen erfassen.

Eine neue onTouchEvent() wird mit einer ACTION_MOVE-Ereignis wenn sich die Position, der Druck oder die Größe des Berührungskontakts ändert. Als im Abschnitt Gängige Touch-Gesten erkennen beschrieben, werden alle werden diese Ereignisse im MotionEvent-Parameter von onTouchEvent()

Da die Berührung mit dem Finger nicht immer die genaueste Form der Interaktion ist, Die Erkennung von Berührungsereignissen basiert oft mehr auf Bewegung als auf einfachen Berührungen. Um Apps zu helfen, zwischen bewegungsbasierten Gesten (wie Wischen) und beweglichen Touch-Gesten wie einmaliges Tippen verwendet, Touch Slop. Der Berührungswinkel bezieht sich auf die Entfernung in Pixeln, die ein Nutzer durch die Berührung erreichen kann. das Wandern, bevor die Geste als bewegungsbasierte Geste interpretiert wird. Weitere Informationen Informationen zu diesem Thema finden Sie unter Touch-Ereignisse in einem ViewGroup haben.

Es gibt mehrere Möglichkeiten, Bewegungen in einer Geste zu verfolgen, je nachdem, die Anforderungen Ihrer Anwendung zu erfüllen. Hier einige Beispiele:

  • Die Start- und Endposition eines Zeigers, z. B. das Bewegen eines Zeigers auf dem Bildschirm von Punkt A nach Punkt B zu verschieben.
  • Die Richtung, in die sich der Zeiger bewegt. Sie wird anhand der X- und Y-Achse bestimmt. Koordinaten.
  • Verlauf. Sie können die Größe des Verlaufs einer Geste abrufen, indem Sie die MotionEvent-Methode getHistorySize() Sie können dann die Positionen, Größen, Zeit und Druck der einzelnen historische Ereignisse mithilfe des Bewegungsereignisses getHistorical<Value> . Das Protokoll ist nützlich, wenn eine Spur des Fingers des Nutzers gerendert wird, z. B. wie Touch-Zeichnungen. Weitere Informationen findest du in der MotionEvent-Referenz.
  • Die Geschwindigkeit des Zeigers, während er sich über den Touchscreen bewegt.

Weitere Informationen finden Sie in den folgenden verwandten Ressourcen:

Trackgeschwindigkeit

Sie können eine bewegungsbasierte Touch-Geste verwenden, die auf der Entfernung oder Richtung basiert bewegt sich der Zeiger. Die Geschwindigkeit ist jedoch oft ein ausschlaggebender Faktor bei der Verfolgung die Eigenschaften einer Geste oder entscheidet, ob die Geste ausgeführt wurde. Um die Berechnung der Geschwindigkeit zu vereinfachen, Android bietet Klasse VelocityTracker. Mit VelocityTracker können Sie die Geschwindigkeit von Berührungsereignissen erfassen. Hilfreich für Gesten, bei denen die Geschwindigkeit Teil des Kriteriums für die Geste ist, z. B. ein Flieger.

Hier ist ein Beispiel, das den Zweck der Methoden in der VelocityTracker-API:

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;
    }
}

Zeigeraufnahme verwenden

Einige Apps, z. B. Spiele, Remote Desktop- und Virtualisierungs-Clients, nicht mehr die Kontrolle über den Mauszeiger bekommen. Zeigeraufnahme ist eine Funktion ab Android 8.0 (API-Level 26) verfügbar. und alle Mausereignisse für eine fokussierte Ansicht in Ihrer App bereitstellen.

Zeigeraufnahme anfordern

Eine Ansicht in Ihrer App kann nur dann die Zeigeraufnahme anfordern, wenn die Ansichtshierarchie, enthält, dass sie hervorgehoben ist. Aus diesem Grund sollte die Zeigererfassung angefordert werden, wenn eine Nutzeraktion während des Aufrufs, z. B. während einer onClick() oder im onWindowFocusChanged() -Event-Handler Ihrer Aktivität.

Um eine Zeigeraufnahme anzufordern, rufen Sie die Methode requestPointerCapture() -Methode für die Ansicht. Das folgende Codebeispiel zeigt, wie ein Zeiger angefordert wird erfassen, wenn der Nutzer auf eine Anzeige klickt:

Kotlin

fun onClick(view: View) {
    view.requestPointerCapture()
}

Java

@Override
public void onClick(View view) {
    view.requestPointerCapture();
}

Sobald die Anfrage zum Erfassen des Zeigers erfolgreich ist, ruft Android onPointerCaptureChange(true) Das System liefert die Mausereignisse in den fokussierten Blick in Ihrer App, solange Sie befindet sich in derselben Ansichtshierarchie wie die Ansicht, die die Erfassung angefordert hat. Sonstiges Apps empfangen erst wieder Mausereignisse, wenn die Erfassung veröffentlicht wird, einschließlich ACTION_OUTSIDE Ereignisse. Android liefert Zeigerereignisse aus anderen Quellen als der Maus als normal, aber der Mauszeiger ist nicht mehr sichtbar.

Erfasste Zeigerereignisse verarbeiten

Sobald für einen Aufruf die Zeigeraufnahme erfolgreich erfasst wurde, liefert Android Mausereignisse. Die fokussierte Ansicht kann die Ereignisse verarbeiten, indem sie eine der folgende Aufgaben ausführen:

Das folgende Codebeispiel zeigt, wie Sie 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;
}

Das folgende Codebeispiel zeigt, wie ein 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;
  }
});

Unabhängig davon, ob Sie eine benutzerdefinierte Ansicht verwenden oder einen Listener registrieren, erhält Ihre Ansicht ein MotionEvent mit Zeigerkoordinaten, die relative Bewegungen angeben, z. B. X oder Y-Deltas, ähnlich den von einem Trackball-Gerät übermittelten Koordinaten. Sie können rufen Sie die Koordinaten ab, getX() und getY()

Zeigeraufnahme loslassen

Die Zeigeraufnahme kann für die Ansicht in Ihrer App durch den Aufruf von releasePointerCapture(), Dies wird im folgenden Codebeispiel gezeigt:

Kotlin

override fun onClick(view: View) {
    view.releasePointerCapture()
}

Java

@Override
public void onClick(View view) {
    view.releasePointerCapture();
}

Das System kann die Aufnahme ohne Sie ausdrücklich aus dem Sichtfeld entfernen. releasePointerCapture() aufgerufen wird. Das liegt in der Regel daran, der die Ansicht enthält, die die Erfassungsanfrage enthält, verliert den Fokus.