Häufig verwendete Bewegungen erkennen

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 →

Eine Berührung erfolgt, wenn ein Nutzer einen oder mehrere Finger auf der und die App interpretiert dieses Berührungsmuster als Geste. Es sind zwei Phasen der Gestenerkennung:

  1. Touch-Ereignisdaten werden erfasst.
  2. Auswerten der Daten, um festzustellen, ob sie die Kriterien für den die von Ihrer App unterstützt werden.

AndroidX-Klassen

In den Beispielen in diesem Dokument wird die Methode GestureDetectorCompat und MotionEventCompat Klassen. Diese Klassen befinden sich in der AndroidX- Mediathek. Verwenden Sie nach Möglichkeit AndroidX-Klassen, um für Kompatibilität mit früheren Geräten. MotionEventCompat ist kein Ersatz für das MotionEvent . Vielmehr bietet es statische Dienstprogrammmethoden, an die Sie Ihre MotionEvent-Objekt, um die damit verknüpfte Aktion zu empfangen .

Datenauswertung

Wenn Nutzende einen oder mehrere Finger auf dem Bildschirm platzieren, wird dadurch die Rückruf onTouchEvent() in der Ansicht, die die Touch-Ereignisse empfängt. Für jede Folge der Berührung wie Position, Druck, Größe und Hinzufügung eines (die als Touch-Geste erkannt wird, onTouchEvent() entspricht mehrere Male ausgelöst wurden.

Die Geste beginnt, wenn der Nutzer den Bildschirm zum ersten Mal berührt, und geht weiter, die Position des Fingers oder der Finger des Nutzers erfasst. dass der letzte Finger den Bildschirm verlässt. Während dieser Interaktion lieferte die MotionEvent onTouchEvent() enthält die Details zu jeder Interaktion. Ihre App anhand der von MotionEvent bereitgestellten Daten feststellen, Geste, die wichtig ist, passiert.

Touch-Ereignisse für eine Aktivität oder Ansicht erfassen

Zum Abfangen von Touch-Ereignissen in einem Activity oder View, überschreibe den onTouchEvent()-Callback.

Im folgenden Code-Snippet wird getAction() um die Aktion des Nutzers aus dem Parameter event zu extrahieren. So erhältst du die erforderlichen Rohdaten, um zu bestimmen, ob eine bestimmte Geste zu diesen Ereignissen.

Kotlin

class MainActivity : Activity() {
    ...
    // This example shows an Activity. You can use the same approach if you are 
    // subclassing a View.
    override fun onTouchEvent(event: MotionEvent): Boolean {
        return when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                Log.d(DEBUG_TAG, "Action was DOWN")
                true
            }
            MotionEvent.ACTION_MOVE -> {
                Log.d(DEBUG_TAG, "Action was MOVE")
                true
            }
            MotionEvent.ACTION_UP -> {
                Log.d(DEBUG_TAG, "Action was UP")
                true
            }
            MotionEvent.ACTION_CANCEL -> {
                Log.d(DEBUG_TAG, "Action was CANCEL")
                true
            }
            MotionEvent.ACTION_OUTSIDE -> {
                Log.d(DEBUG_TAG, "Movement occurred outside bounds of current screen element")
                true
            }
            else -> super.onTouchEvent(event)
        }
    }
}

Java

public class MainActivity extends Activity {
...
// This example shows an Activity. You can use the same approach if you are
// subclassing a View.
@Override
public boolean onTouchEvent(MotionEvent event){
    switch(event.getAction()) {
        case (MotionEvent.ACTION_DOWN) :
            Log.d(DEBUG_TAG,"Action was DOWN");
            return true;
        case (MotionEvent.ACTION_MOVE) :
            Log.d(DEBUG_TAG,"Action was MOVE");
            return true;
        case (MotionEvent.ACTION_UP) :
            Log.d(DEBUG_TAG,"Action was UP");
            return true;
        case (MotionEvent.ACTION_CANCEL) :
            Log.d(DEBUG_TAG,"Action was CANCEL");
            return true;
        case (MotionEvent.ACTION_OUTSIDE) :
            Log.d(DEBUG_TAG,"Movement occurred outside bounds of current screen element");
            return true;
        default :
            return super.onTouchEvent(event);
    }
}

Dieser Code erzeugt Meldungen wie die folgende in Logcat, wenn der Benutzer tippt: berührt und „Holds“ und „Drags“:

GESTURES D   Action was DOWN
GESTURES D   Action was UP
GESTURES D   Action was MOVE

Bei benutzerdefinierten Touch-Gesten können Sie diese Ereignisse selbst feststellen, ob sie eine Geste darstellen, die du verarbeiten musst. Wenn Ihre App verwendet gängige Touch-Gesten wie Doppeltippen, Tippen und „Halten“, „Fingen“ usw. können Sie die Vorteile GestureDetector . Mit GestureDetector lassen sich häufige ohne die einzelnen Touch-Ereignisse selbst zu verarbeiten. Dies ist Gesten erkennen.

Touch-Ereignisse für eine einzige Ansicht erfassen

Als Alternative zu onTouchEvent() können Sie ein View.OnTouchListener Objekt zu einem beliebigen View mithilfe der Methode setOnTouchListener() . Dadurch ist es möglich, auf Touch-Ereignisse zu warten, ohne eine abgeleitete Klasse von vorhandene View, wie im folgenden Beispiel gezeigt:

Kotlin

findViewById<View>(R.id.my_view).setOnTouchListener { v, event ->
    // Respond to touch events.
    true
}

Java

View myView = findViewById(R.id.my_view);
myView.setOnTouchListener(new OnTouchListener() {
    public boolean onTouch(View v, MotionEvent event) {
        // Respond to touch events.
        return true;
    }
});

Achten Sie darauf, einen Listener zu erstellen, der false für den Ereignis vom Typ ACTION_DOWN. In diesem Fall wird der Listener für den nachfolgenden ACTION_MOVE und ACTION_UP-Sequenz von Ereignisse. Das liegt daran, dass ACTION_DOWN der Ausgangspunkt für alle Touch-Events.

Wenn Sie eine benutzerdefinierte Ansicht erstellen, onTouchEvent(), wie zuvor beschrieben.

Gesten erkennen

Android bietet die GestureDetector-Klasse zum Erkennen gängiger Gesten verwenden. Einige der unterstützten Touch-Gesten sind u. a. onDown(), onLongPress(), und onFling() Sie können GestureDetector in Verbindung mit dem onTouchEvent()-Methode.

Alle unterstützten Touch-Gesten erkennen

Wenn Sie ein GestureDetectorCompat-Objekt instanziieren, wird eine der ist eine Klasse, die das GestureDetector.OnGestureListener . GestureDetector.OnGestureListener benachrichtigt Nutzer, wenn ein bestimmtes Touch-Ereignis auftritt. Damit Ihr Unternehmen GestureDetector-Objekt, um Ereignisse zu erhalten, die Ansicht oder onTouchEvent()-Methode der Aktivität und leiten alle beobachteten Ereignisse weiter an die Detektorinstanz übergeben.

Im folgenden Snippet wird der Rückgabewert true aus dem einzelne on<TouchEvent>-Methoden an, dass die Touch-Ereignis verarbeitet wird. Ein Rückgabewert von false übergibt Ereignisse ab. durch den Ansichtsstapel bis zur Berührung.

Wenn Sie das folgende Snippet in einer Test-App ausführen, Aktionen ausgelöst werden, wenn Sie mit dem Touchscreen interagieren und Die Inhalte von MotionEvent gelten für jedes Touch-Ereignis. Sie sehen dann wie viele Daten für einfache Interaktionen generiert werden.

Kotlin

private const val DEBUG_TAG = "Gestures"

class MainActivity :
        Activity(),
        GestureDetector.OnGestureListener,
        GestureDetector.OnDoubleTapListener {

    private lateinit var mDetector: GestureDetectorCompat

    // Called when the activity is first created.
    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // Instantiate the gesture detector with the
        // application context and an implementation of
        // GestureDetector.OnGestureListener.
        mDetector = GestureDetectorCompat(this, this)
        // Set the gesture detector as the double-tap
        // listener.
        mDetector.setOnDoubleTapListener(this)
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        return if (mDetector.onTouchEvent(event)) {
            true
        } else {
            super.onTouchEvent(event)
        }
    }

    override fun onDown(event: MotionEvent): Boolean {
        Log.d(DEBUG_TAG, "onDown: $event")
        return true
    }

    override fun onFling(
            event1: MotionEvent,
            event2: MotionEvent,
            velocityX: Float,
            velocityY: Float
    ): Boolean {
        Log.d(DEBUG_TAG, "onFling: $event1 $event2")
        return true
    }

    override fun onLongPress(event: MotionEvent) {
        Log.d(DEBUG_TAG, "onLongPress: $event")
    }

    override fun onScroll(
            event1: MotionEvent,
            event2: MotionEvent,
            distanceX: Float,
            distanceY: Float
    ): Boolean {
        Log.d(DEBUG_TAG, "onScroll: $event1 $event2")
        return true
    }

    override fun onShowPress(event: MotionEvent) {
        Log.d(DEBUG_TAG, "onShowPress: $event")
    }

    override fun onSingleTapUp(event: MotionEvent): Boolean {
        Log.d(DEBUG_TAG, "onSingleTapUp: $event")
        return true
    }

    override fun onDoubleTap(event: MotionEvent): Boolean {
        Log.d(DEBUG_TAG, "onDoubleTap: $event")
        return true
    }

    override fun onDoubleTapEvent(event: MotionEvent): Boolean {
        Log.d(DEBUG_TAG, "onDoubleTapEvent: $event")
        return true
    }

    override fun onSingleTapConfirmed(event: MotionEvent): Boolean {
        Log.d(DEBUG_TAG, "onSingleTapConfirmed: $event")
        return true
    }

}

Java

public class MainActivity extends Activity implements
        GestureDetector.OnGestureListener,
        GestureDetector.OnDoubleTapListener{

    private static final String DEBUG_TAG = "Gestures";
    private GestureDetectorCompat mDetector;

    // Called when the activity is first created.
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Instantiate the gesture detector with the
        // application context and an implementation of
        // GestureDetector.OnGestureListener.
        mDetector = new GestureDetectorCompat(this,this);
        // Set the gesture detector as the double-tap
        // listener.
        mDetector.setOnDoubleTapListener(this);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event){
        if (this.mDetector.onTouchEvent(event)) {
            return true;
        }
        return super.onTouchEvent(event);
    }

    @Override
    public boolean onDown(MotionEvent event) {
        Log.d(DEBUG_TAG,"onDown: " + event.toString());
        return true;
    }

    @Override
    public boolean onFling(MotionEvent event1, MotionEvent event2,
            float velocityX, float velocityY) {
        Log.d(DEBUG_TAG, "onFling: " + event1.toString() + event2.toString());
        return true;
    }

    @Override
    public void onLongPress(MotionEvent event) {
        Log.d(DEBUG_TAG, "onLongPress: " + event.toString());
    }

    @Override
    public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX,
            float distanceY) {
        Log.d(DEBUG_TAG, "onScroll: " + event1.toString() + event2.toString());
        return true;
    }

    @Override
    public void onShowPress(MotionEvent event) {
        Log.d(DEBUG_TAG, "onShowPress: " + event.toString());
    }

    @Override
    public boolean onSingleTapUp(MotionEvent event) {
        Log.d(DEBUG_TAG, "onSingleTapUp: " + event.toString());
        return true;
    }

    @Override
    public boolean onDoubleTap(MotionEvent event) {
        Log.d(DEBUG_TAG, "onDoubleTap: " + event.toString());
        return true;
    }

    @Override
    public boolean onDoubleTapEvent(MotionEvent event) {
        Log.d(DEBUG_TAG, "onDoubleTapEvent: " + event.toString());
        return true;
    }

    @Override
    public boolean onSingleTapConfirmed(MotionEvent event) {
        Log.d(DEBUG_TAG, "onSingleTapConfirmed: " + event.toString());
        return true;
    }
}

Bestimmte unterstützte Touch-Gesten erkennen

Wenn Sie nur wenige Gesten verarbeiten möchten, können Sie GestureDetector.SimpleOnGestureListener anstatt die GestureDetector.OnGestureListener zu implementieren, .

GestureDetector.SimpleOnGestureListener bietet ein Implementierung für alle on<TouchEvent>-Methoden, indem Sie false für alle. So können Sie nur die Methoden überschreiben, die Ihnen wichtig sind. Mit dem folgenden Code-Snippet wird beispielsweise eine Klasse erstellt, GestureDetector.SimpleOnGestureListener und Überschreibungen onFling() und onDown().

Ob Sie GestureDetector.OnGestureListener oder GestureDetector.SimpleOnGestureListener, ist es eine Best Practice, Implementieren Sie eine onDown()-Methode, die true zurückgibt. Dieses liegt daran, dass alle Touch-Gesten mit einer onDown()-Nachricht beginnen. Wenn Sie false von onDown() zurückgeben als GestureDetector.SimpleOnGestureListener tut das standardmäßig, das System wird angenommen, dass Sie den Rest der Bewegung sowie die anderen Methoden der GestureDetector.OnGestureListener werden nicht angerufen. Dies kann dazu führen, unerwartete Probleme in Ihrer App auftreten. Nur false zurückgeben ab onDown(), wenn du wirklich eine ganze Geste ignorieren möchtest.

Kotlin

private const val DEBUG_TAG = "Gestures"

class MainActivity : Activity() {

    private lateinit var mDetector: GestureDetectorCompat

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        mDetector = GestureDetectorCompat(this, MyGestureListener())
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        mDetector.onTouchEvent(event)
        return super.onTouchEvent(event)
    }

    private class MyGestureListener : GestureDetector.SimpleOnGestureListener() {

        override fun onDown(event: MotionEvent): Boolean {
            Log.d(DEBUG_TAG, "onDown: $event")
            return true
        }

        override fun onFling(
                event1: MotionEvent,
                event2: MotionEvent,
                velocityX: Float,
                velocityY: Float
        ): Boolean {
            Log.d(DEBUG_TAG, "onFling: $event1 $event2")
            return true
        }
    }
}

Java

public class MainActivity extends Activity {

    private GestureDetectorCompat mDetector;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDetector = new GestureDetectorCompat(this, new MyGestureListener());
    }

    @Override
    public boolean onTouchEvent(MotionEvent event){
        if (this.mDetector.onTouchEvent(event)) {
              return true;
        }
        return super.onTouchEvent(event);
    }

    class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
        private static final String DEBUG_TAG = "Gestures";

        @Override
        public boolean onDown(MotionEvent event) {
            Log.d(DEBUG_TAG,"onDown: " + event.toString());
            return true;
        }

        @Override
        public boolean onFling(MotionEvent event1, MotionEvent event2,
                float velocityX, float velocityY) {
            Log.d(DEBUG_TAG, "onFling: " + event1.toString() + event2.toString());
            return true;
        }
    }
}

Weitere Informationen