Apps für Android programmieren leicht gemacht!
wischgesten erkennen

Wischgesten erkennen

Es kann in vielen Situationen und Anwendungsbereichen von großem Vorteil sein Wischgesten erkennen zu können.
Beispielsweise könnte man diese in einem Spiel verwenden oder eine bestimmte Funktion innerhalb einer App ausführen, wenn man eine Wischgeste erkennt.
Aus diesem Grund werden wir uns in diesem Artikel mit dem Erkennen dieser Gesten in einer eignen Java Klasse beschäftigen.

 

Funktionsweise:

Vielleicht sollten wir uns vorerst mit der Thematik der Wischgesten beschäftigen.
Wie zum Teufel erkennt Android diese Gesten?

Naja Grundlegend ist die Erkennung recht simpel.
Wir haben eine Funktion (einen sogenannten Listener), die immer dann ausgeführt wird, wenn man mit dem Bildschirm interagiert. Diese Interaktionen können sich dabei auf das grundlegendste, wie das absenken des Fingers auf den Bildschirm oder anheben des Fingers von dem Bildschirm, beschränken. Diese beiden Events reichen uns schon.
Nun nehmen wir weiterhin an der Bildschirm besitzt eine X- und eine Y-Koordinate. Der Wert X dieser Koordinaten bestimmt die horizontale Position des Fingers und der Wert Y die vertikale Position des Fingers.

Nun hätten wir alles beisammen.
Die Wischgestenerkennung funktioniert nun folgendermaßen:
Als erstes setzt der Nutzer den Finger auf den Bildschirm ab und die Anfangsposition des Fingers wird durch die X- und Y-Koordinaten gespeichert.
Nun wischt der Nutzer mit dem Finger nach oben und hebt den Finger nun anschließend wieder an. Beim Anheben des Fingers speichern wir ebenfalls die letzten X- und Y-Koordinaten.
Anschließend berechnen wir die Differenz der beiden X-Werte und der beiden Y-Werte.
Ist die Differenz der X-Werte deutlich größer als die der Y-Werte wurde der Finger nach links oder rechts gewischt.
Ist hingegen die Differenz der Y-Werte größer als die Differenz der X-Werte wurde der Finger nach oben oder unten gewischt.

Um nun letztendlich noch zu erkennen ob der Finger denn nach links oder nach rechts bewegt wurde schaut man sich an, ob die Differenz der beiden X-Werte negativ oder positiv ist.
Die Erkennung zwischen oben und unten funktioniert, mit den Y-Werten, genau so.

Beispiel:
Abgesenkt: X = 100, Y = 0
Angehoben: X = 50, Y = 1
Differenz X: 50 – 100 = -50
Differenz Y: 1 – 0 = 1

Da die Differenz von X größer ist als die von Y und die Differenz von X kleiner ist als 0 wurde der Finger nach links bewegt.

 

Programmierung:

Genug der grauen Theorie, fangen wir an die Wischgestenerkennung zu programmieren.
Spätestens am Ende dieses Artikels kann die App Wischgesten erkennen.

Wir verwenden der Einfachheit und Übersichtlichkeit halber eine neue Klasse.
Diese Klasse nennen wir kurzerhand „Gesten“ und erstellen sie im gleichen Package, wo all unsere anderen Klassen ebenfalls liegen.
Anschließend können wir jedes x-beliebige View mit dieser Klasse ausstatten und Wischgesten erkennen. Zudem müssen wir nicht für jedes View eine neue Funktion schreiben, es reicht die Klasse wiederzuverwenden.

Gesten.class:

import android.content.Context;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

public class Gesten implements View.OnTouchListener {

    private GestureDetector gestureDetector = null;
    private Context cxt = null;

    public Gesten(Context context) {
        gestureDetector = new GestureDetector(context, new GestureListener());
        cxt = context;
    }

    public boolean onTouch(View v, MotionEvent event) {
        boolean res = gestureDetector.onTouchEvent(event);
        return res;
    }

    private final class GestureListener extends GestureDetector.SimpleOnGestureListener {

        private static final int SWIPE_THRESHOLD = 100;
        private static final int SWIPE_VELOCITY_THRESHOLD = 100;

        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            boolean result = false;
            try {
                float diffY = e2.getY() - e1.getY();
                float diffX = e2.getX() - e1.getX();
                if (Math.abs(diffX) > Math.abs(diffY)) {
                    if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffX > 0) {
                            result = onSwipeRight();
                        } else {
                            result = onSwipeLeft();
                        }
                    }else{
                        result = nichts();
                    }
                } else {
                    if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffY > 0) {
                            result = onSwipeBottom();
                        } else {
                            result = onSwipeTop();
                        }
                    }else{
                        result = nichts();
                    }
                }
            } catch (Exception exception) {
                exception.printStackTrace();
            }
            return result;
        }
    }

    public boolean onSwipeRight() {
        return false;
    }

    public boolean onSwipeLeft() {
        return false;
    }

    public boolean nichts(){
        return false;
    }

    public boolean onSwipeTop() {
        return false;
    }

    public boolean onSwipeBottom() {
        return false;
    }

}

 

Zugegeben diese Klasse sieht am Anfang etwas „Monströs“ aus, ist aber in ihrer Verwendung mehr als einfach.
Wir verwenden die soeben erstellt Klasse nun folgendermaßen:

Als erstes suchen wir uns ein View-Element aus, welches auf die Wischgesten hin geprüft werden soll.
In der Regel handelt es sich bei diesem View, um das Layout im Hintergrund. Das layout sollte Idealerweise über das gesamte Sichtfeld des Smartphones gehen.
Anschließend beschreiben wir eine beliebige Variable mit diesem View und wenden auf diese Variable folgenden Code an:

RelativeLayout BG = (RelativeLayout) findViewById(R.id.spielfeldhintergrund);

BG.setOnTouchListener(new Gesten(this) {
   public boolean onSwipeTop() {
      //es wurde nach oben gewischt, hier den Code einfügen
      return false;
   }
   public boolean onSwipeRight() {
      //es wurde nach rechts gewischt, hier den Code einfügen
      return false;
   }
   public boolean onSwipeLeft() {
      //es wurde nach links gewischt, hier den Code einfügen
      return false;
   }
   public boolean onSwipeBottom() {
      //es wurde nach unten gewischt, hier den Code einfügen
      return false;
   }
   public boolean nichts(){
      //es wurde keine wischrichtung erkannt, hier den Code einfügen    
      return false;
   }
});

 

Als Beispiel haben wir nun einmal als View „spielfeldhintergrund“ gewählt.
Dieses geht in unserer App über den gesamten Bildschirm.
Was wir nun genau für Aktionen ausführen wollen schreiben wir in den 2. Code an die gekennzeichneten Stellen.
Da wir nun eine Klasse verwendet haben, bei der die Funktionen leer sind können wir die Funktionen überladen. Dieses Überladen der Funktionen hat den Vorteil, dass wir nicht für jedes View den langen Code aus der Klasse „Gesten“ neu schreiben müssen, sondern nur die 5 Funktionen überladen.

Viel Spaß beim Wischgesten erkennen 😉

Marvin

Ich bin 23 Jahre jung und studiere zurzeit Wirtschaftsinformatik an der Georg-August-Universität in Göttingen. Ich bin ein Mensch, der sich neben der Programmierung noch für tausend andere Dinge interessiert, die mal mehr und mal weniger verrückt sind. Vor allem aber bin ich Feuer und Flamme mit der Programmierung von eigenen kleinen Apps und Programmen, die mein Leben bereichern.

1 Kommentar

*Pflichtfeld

  • Funktioniert wunderbar. Hab noch ein Klick Event mit eingebaut damit Klicks auch über die gesten Klasse mit abgefangen werden können. Dazu in der Gesten Klasse in Klasse GestureListener folgende Funktion dazu:

    @Override
    public boolean onSingleTapUp( MotionEvent e ) {
    return onClick();
    }

    Und in der Klasse Gesten die onClick Funktion rein:

    public boolean onClick() {
    return false;
    }

    Die Funktion onClick kann beim setzen des setOnTouchListener mit überladen und so auch Klicks mit verarbeitet werden.