Wie "SimpleGestureListener"-Klasse einbinden?

N

no1Ltan

Fortgeschrittenes Mitglied
Threadstarter
Hallo,

ich habe im Internet eine Klasse gefunden, mit der man Touch-Gesten in seine App einbinden kann.
Mit Touch-Gesten meine ich horizontales und vertikales Wischen.

Der Code dieser Klasse:

Code:
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;

/**
 * Created by CoXier on 17-2-21.
 */

public class SimpleGestureListener extends GestureDetector.SimpleOnGestureListener {
    private static final String TAG = "SimpleGestureListener";
    private Listener mListener;

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

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        Log.i(TAG,e1.toString()+"\n"+e2.toString());
        Log.d(TAG,"distanceX = "+distanceX+",distanceY = "+distanceY);
        if (mListener == null)
            return true;

        if (distanceX == 0 && Math.abs(distanceY) > 1){
            mListener.onScrollVertical(distanceY);
        }

        if (distanceY == 0 && Math.abs(distanceX) > 1){
            mListener.onScrollHorizontal(distanceX);
        }
        return true;
    }


    public void setListener(Listener mListener) {
        this.mListener = mListener;
    }

    interface Listener{
        /**
         * left scroll dx >0
         * right scroll dx <0
         * @param dx
         */
        void onScrollHorizontal(float dx);

        /**
         * upward scroll dy > 0
         * downward scroll dy < 0
         * @param dy
         */
        void onScrollVertical(float dy);
    }
}
Hier ein Beispiel des Code-Schreibers, wie man die Klasse implementieren kann:

Code:
public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private GestureDetector mDetector;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        SimpleGestureListener simpleGestureListener = new SimpleGestureListener();
        simpleGestureListener.setListener(new SimpleGestureListener.Listener() {
            @Override
            public void onScrollHorizontal(float dx) {
                Log.i(TAG,"horizontal = " +dx);
            }

            @Override
            public void onScrollVertical(float dy) {
                Log.i(TAG,"vertical = " +dy);
            }
        });
        mDetector = new GestureDetector(this, simpleGestureListener);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mDetector.onTouchEvent(event);
        return super.onTouchEvent(event);
    }
}
Die Klasse habe ich bereits mittels Rechtsklick auf App -> New -> Java Class hinzugefügt.
Allerdings ist mein Problem, dass ich keine einzelne Activity habe,
sondern eine MainActivity und 3 Fragmente, die ich mittels ViewPager hin- und herwechsele.
Meine MainActivity ist "nur" das Grundgerüst.

Ich würde gerne diese SimpleGestureListener-Funktionalität in 1 Fragment benutzen.
(Allerdings nur die nach oben bzw. nach unten-Wischen Geste - um z.B. Methoden aufzurufen).

Muss ich den SimpleGestureListener trotzdem in die MainActivity einbinden (so wie im Beispiel oben)
oder reicht es in dem Fall dies in meinem Ziel-Fragment zu tun?

Ich hatte es genau wie in dem Beispiel oben gemacht.
Allerdings zeigt mir die Log nichts an, sobald ich nach oben oder unten wische.
Daher vermute ich, dass es in meinem Fall nicht in die MainActivity gehört.

Meine App kennt ihr ja schon: :)
Wie viele Klassen und Layouts brauche ich für meine App?

Grüße
 
Jaiel

Jaiel

Experte
Das steht in Activity | Android Developers :

public boolean onTouchEvent (MotionEvent event)

Called when a touch screen event was not handled by any of the views under it. This is most useful to process touch events that happen outside of your window bounds, where there is no view to receive it.
Normalerweise machst du touch-listener an Views und nicht an Komponenten wie Activities oder Fragments
 
J

jogimuc

Erfahrenes Mitglied
Hallo Hast du den Code auch mal in einer reinen Activity getestet ob er auch koreckt arbeitet?

Jaiel in diesem fall ist das schon richtig es nicht nur auf eine View anzuwenden. Er will ja ein Event haben wenn der Bildschirm berürt wird und diese reicht er an seine Klasse den listner weiter .

es könnte aber auch sein das der viewpager den Scroll listner überschreibt und nicht zurück gibt also die superklasse nicht aufruft.
setze mal ein log in die onTouchEvent in der main. wenn du den bidschirm berührst solten da logs kommen.
wenn nicht versuche es mal iim Fragment einfach überschreiben und superkalsse aufrufen und log.
 
Zuletzt bearbeitet:
N

no1Ltan

Fortgeschrittenes Mitglied
Threadstarter
Hallo,

hab soeben ein neues Projekt erstellt, welches aus nur 1 Activity und 1 Layout besteht.
Ich habe die SimpleGestureListener-Klasse importiert und in die MainActivity integriert (wie oben beschrieben).
Also es funktioniert einwandfrei!

Hab es auch so gemacht, dass nach oben wischen eine andere Funktion als nach unten wischen bewirkt.
(Nur als kleinen Test.)
Das horizontale Wischen funktionierte auch, hab's aber nachträglich rausgenommen.

MainActivity.java:
Code:
import android.support.constraint.ConstraintLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;

public class MainActivity extends AppCompatActivity
{
    private static final String TAG = "MainActivity";
    private GestureDetector mDetector;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        SimpleGestureListener simpleGestureListener = new SimpleGestureListener();
        simpleGestureListener.setListener(new SimpleGestureListener.Listener()
        {
            @Override
            public void onScrollHorizontal(float dx)
            {
                //Log.i(TAG,"horizontal = " +dx); - LOG WORKS CORRECTLY!
/*                ConstraintLayout constraintLayout = findViewById(R.id.constraint_layout);
                constraintLayout.setBackgroundColor(getResources().getColor(R.color.colorAccent));*/
            }

            @Override
            public void onScrollVertical(float dy)
            {
                //Log.i(TAG,"vertical = " +dy); - LOG WORKS CORRECTLY!
                ConstraintLayout constraintLayout = findViewById(R.id.constraint_layout);
                if (dy > 0)
                {
                    constraintLayout.setBackgroundColor(getResources().getColor(R.color.blue));
                }
                if (dy < 0)
                {
                    constraintLayout.setBackgroundColor(getResources().getColor(R.color.yellow));
                }
            }
        });
        mDetector = new GestureDetector(this, simpleGestureListener);
    }

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

Bei meiner "echten App" bekomme ich immer Fehlermeldungen, sobald ich


Code:
mDetector = new GestureDetector(this, simpleGestureListener);
und
Code:
    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        mDetector.onTouchEvent(event);
        return super.onTouchEvent(event);
    }
in ein Fragment einfügen will.

Beim 1. Code meint er:
"Cannot resolve constructor."

Bei Codeblock 2:
"Method does not override method from its superclass".
"Cannot resolve method 'onTouchEvent(android.view.MotionEvent)'

Der Unterschied bei meinen Fragmenten ist ja, dass ich keine onCreated habe, sondern eine onCreateView.

Grüße
 
J

jogimuc

Erfahrenes Mitglied
Bin gerade unterwegs schaue später. Aber hast du mal das gemacht was ich gesagt habe bei deinen fragment in der Main die Methode onTouchEvent zu überschreiben und ein log zu machen. Möchte wissen ob die Methode auch aus einem fragment in der Main aufgerufen wird.

Denn bei fragment kommen die Events in der activity an und nicht in der Fragment klasse.

Bei Fragment kannst du die onActivityCreated als deine oncreat benutzen.
 
Zuletzt bearbeitet:
J

jogimuc

Erfahrenes Mitglied
Hi also block zwei muss in der activity bleiben im Fragment gibst es die Methode nicht deshalb kannst du es auch nicht überschreiben.

Wenn du den listner die Klasse in deinem Fragment initialisiert mist du auch den Content der Activity benutzen.
mDetector = new GestureDetector(getActivity(), simpleGestureListener);
Die Vaiable mDetector solltest du static machen um aus der Aktivity darauf zugreifen zu können. In der
@override
public boolean onTouchEvent(MotionEvent event)
{
mDetector.onTouchEvent(event);
return super.onTouchEvent(event);
}
musst du mit den Klassennamen auf mDetector zugreifen vor allen solltest du vorher prüfen ob auch die Page 2 gerade aktiv ist wenn nicht kann die App abstürzen.
 
Thread starter Similar threads Forum Replies Date
N Android App Entwicklung 37
Oben Unten