Wie erkenne ich das Wischen nach links oder rechts in Android?

92

Ich habe einen EditTextBlick in Android. Darauf möchte ich ein Wischen nach links oder rechts erkennen. Ich kann es mit dem folgenden Code auf eine leere Stelle bringen. Aber das funktioniert nicht, wenn ich auf einem wische EditText. Wie mache ich das? Bitte lassen Sie mich wissen, wenn ich etwas falsch mache. Danke dir.

Verwendeter Code:

switch (touchevent.getAction())
{
    case MotionEvent.ACTION_DOWN:
    {
        oldTouchValue = touchevent.getX();
        break;
    }
    case MotionEvent.ACTION_UP:
    {
        float currentX = touchevent.getX();
        if (oldTouchValue < currentX)
        {
            // swiped left
        }
        if (oldTouchValue > currentX )
        {
            swiped right
        }
    break;
    }
}
Vinod
quelle
Hilfreiches Tutorial für diese Anforderung techrepublic.com/blog/software-engineer/…
amitabha2715

Antworten:

109

Einfachster Wischdetektor von links nach rechts:

Fügen Sie in Ihrer Aktivitätsklasse folgende Attribute hinzu:

private float x1,x2;
static final int MIN_DISTANCE = 150;

und onTouchEvent()Methode überschreiben :

@Override
public boolean onTouchEvent(MotionEvent event)
{     
    switch(event.getAction())
    {
      case MotionEvent.ACTION_DOWN:
          x1 = event.getX();                          
      break;          
      case MotionEvent.ACTION_UP:
          x2 = event.getX();
          float deltaX = x2 - x1;
          if (Math.abs(deltaX) > MIN_DISTANCE)
          {
              Toast.makeText(this, "left2right swipe", Toast.LENGTH_SHORT).show ();
          }
          else
          {
              // consider as something else - a screen tap for example
          }                       
      break;    
    }            
    return super.onTouchEvent(event);        
}
user2999943
quelle
danke, dass es funktioniert, aber können Sie mir bitte sagen, wie es funktioniert, wenn es eine scrollView gibt?
LS_
Da getAction()gemischte Daten sowohl des Aktionstyps als auch des Zeigerindex zurückgegeben werden, ist es nicht besser, diese zu verwenden getActionMasked(), die nur den Aktionstyp zurückgeben.
Lartkma
Diese Lösung ist veraltet. Jetzt können Sie die onFling-Geste verwenden.
Donato
58

Ich mag den Code von @ user2999943. Aber nur ein paar kleine Änderungen für meine eigenen Zwecke.

@Override
public boolean onTouchEvent(MotionEvent event)
{     
    switch(event.getAction())
    {
      case MotionEvent.ACTION_DOWN:
          x1 = event.getX();                         
      break;         
      case MotionEvent.ACTION_UP:
          x2 = event.getX();
          float deltaX = x2 - x1;

          if (Math.abs(deltaX) > MIN_DISTANCE)
          {
              // Left to Right swipe action
              if (x2 > x1)
              {
                  Toast.makeText(this, "Left to Right swipe [Next]", Toast.LENGTH_SHORT).show ();                     
              }

              // Right to left swipe action               
              else 
              {
                  Toast.makeText(this, "Right to Left swipe [Previous]", Toast.LENGTH_SHORT).show ();                    
              }

          }
          else
          {
              // consider as something else - a screen tap for example
          }                          
      break;   
    }           
    return super.onTouchEvent(event);       
}
Rudi Strydom
quelle
1
Hey, es scheint, dass dieser Code nicht funktioniert, wenn er sich in einer Aktivität mit einer ScrollView befindet. Irgendeine Idee warum? Ansonsten toller Code
Jona
Jona, dieselbe Ansicht muss in der Lage sein, die Ereignisse ACTION_DOWN und ACTION_UP aufzunehmen, damit dies funktioniert.
Al Wang
@ AlWang was meinst du?
JK
Es scheint, dass in Jonas Fall die ScrollView das MotionEvent abfängt. Eine Implementierung finden Sie unter stackoverflow.com/questions/12884250/… .
Al Wang
Kannst du mir sagen, wie man auch Auf- und Abwischen erkennt
Maulik
32

Dies ist eine nette Klasse, die ich verwende (in Fällen, in denen ich ein Ereignis in einer Ansicht abfangen möchte, wenn es sich um eine ViewGroup handelt, verwende ich die zweite Implementierung):

import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class SwipeDetector implements View.OnTouchListener{

    private int min_distance = 100;
    private float downX, downY, upX, upY;
    private View v;

    private onSwipeEvent swipeEventListener;



    public SwipeDetector(View v){
        this.v=v;
        v.setOnTouchListener(this);
    }

    public void setOnSwipeListener(onSwipeEvent listener)
    {
        try{
            swipeEventListener=listener;
        }
        catch(ClassCastException e)
        {
            Log.e("ClassCastException","please pass SwipeDetector.onSwipeEvent Interface instance",e);
        }
    }


    public void onRightToLeftSwipe(){
        if(swipeEventListener!=null)
            swipeEventListener.SwipeEventDetected(v,SwipeTypeEnum.RIGHT_TO_LEFT);
        else
            Log.e("SwipeDetector error","please pass SwipeDetector.onSwipeEvent Interface instance");
    }

    public void onLeftToRightSwipe(){
        if(swipeEventListener!=null)
            swipeEventListener.SwipeEventDetected(v,SwipeTypeEnum.LEFT_TO_RIGHT);
        else
            Log.e("SwipeDetector error","please pass SwipeDetector.onSwipeEvent Interface instance");
    }

    public void onTopToBottomSwipe(){
        if(swipeEventListener!=null)
            swipeEventListener.SwipeEventDetected(v,SwipeTypeEnum.TOP_TO_BOTTOM);
        else
            Log.e("SwipeDetector error","please pass SwipeDetector.onSwipeEvent Interface instance");
    }

    public void onBottomToTopSwipe(){
        if(swipeEventListener!=null)
            swipeEventListener.SwipeEventDetected(v,SwipeTypeEnum.BOTTOM_TO_TOP);
        else
            Log.e("SwipeDetector error","please pass SwipeDetector.onSwipeEvent Interface instance");
    }

    public boolean onTouch(View v, MotionEvent event) {
        switch(event.getAction()){
        case MotionEvent.ACTION_DOWN: {
            downX = event.getX();
            downY = event.getY();
            return true;
        }
        case MotionEvent.ACTION_UP: {
            upX = event.getX();
            upY = event.getY();

            float deltaX = downX - upX;
            float deltaY = downY - upY;

            //HORIZONTAL SCROLL
            if(Math.abs(deltaX) > Math.abs(deltaY))
            {
                if(Math.abs(deltaX) > min_distance){
                    // left or right
                    if(deltaX < 0) 
                    {
                        this.onLeftToRightSwipe();
                        return true;
                    }
                    if(deltaX > 0) {
                        this.onRightToLeftSwipe();
                        return true; 
                    }
                }
                else {
                    //not long enough swipe...
                    return false; 
                }
            }
            //VERTICAL SCROLL
            else 
            {
                if(Math.abs(deltaY) > min_distance){
                    // top or down
                    if(deltaY < 0) 
                    { this.onTopToBottomSwipe();
                    return true; 
                    }
                    if(deltaY > 0)
                    { this.onBottomToTopSwipe(); 
                    return true;
                    }
                }
                else {
                    //not long enough swipe...
                    return false;
                }
            }

            return true;
        }
        }
        return false;
    }
    public interface onSwipeEvent
    {
        public void SwipeEventDetected(View v, SwipeTypeEnum SwipeType);
    }

    public SwipeDetector setMinDistanceInPixels(int min_distance)
{
    this.min_distance=min_distance;
    return this;
}

    public enum SwipeTypeEnum
    {
        RIGHT_TO_LEFT,LEFT_TO_RIGHT,TOP_TO_BOTTOM,BOTTOM_TO_TOP
    }

}

und dies ist ein Anwendungsbeispiel:

filters_container=(RelativeLayout)root.findViewById(R.id.filters_container);
    new SwipeDetector(filters_container).setOnSwipeListener(new SwipeDetector.onSwipeEvent() {
        @Override
        public void SwipeEventDetected(View v, SwipeDetector.SwipeTypeEnum swipeType) {
            if(swipeType==SwipeDetector.SwipeTypeEnum.LEFT_TO_RIGHT)
                getActivity().onBackPressed();
        }
    });

In einigen Fällen möchten Sie die Wischgesten in einem Container erkennen und die Berührungsereignisse an die untergeordneten Elemente weitergeben, sodass Sie in diesem Fall eine benutzerdefinierte Ansichtsgruppe erstellen können, z. B. RelativeLayout, und onInterceptTouchEvent überschreiben können, und dort das Wischereignis erkennen können ohne den Durchgang von Touch Event zu Ihren untergeordneten Ansichten zu blockieren, zum Beispiel:

    import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.RelativeLayout;


public class SwipeDetectRelativeLayout extends RelativeLayout {


    private float x1,x2;
    static final int MIN_DISTANCE=150;
    private onSwipeEventDetected mSwipeDetectedListener;


    public SwipeDetectRelativeLayout(Context context) {
        super(context);
    }

    public SwipeDetectRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SwipeDetectRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        switch(ev.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                x1 = ev.getX();
                break;
            case MotionEvent.ACTION_UP:
                x2 = ev.getX();
                float deltaX = x2 - x1;
                if (Math.abs(deltaX) > MIN_DISTANCE)
                {
                        //swiping right to left
                        if(deltaX<0)
                        {
                            if(mSwipeDetectedListener!=null)
                                mSwipeDetectedListener.swipeEventDetected();
                        }
                }
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }

    public interface onSwipeEventDetected
    {
        public void swipeEventDetected();
    }

    public void registerToSwipeEvents(onSwipeEventDetected listener)
    {
        this.mSwipeDetectedListener=listener;
    }
}
Gal Rom
quelle
Hervorragende Implementierung, ich habe die erste Option verwendet und auch Unterstützung für onTouch hinzugefügt, also habe ich die nächsten vorherigen und onTouch behandelt, danke!
Ziniestro
@Gal Rom Wie benutzt man die zweite Methode?
Smoothdvd
Hervorragende Antwort! Es funktioniert definitiv mit sehr wenig Aufwand und super effektiv.
Xarlymg89
Tolle Implementierung.
Tugrul
9

Swipe-Ereignisse sind eine Art von onTouchEreignissen. Vereinfachen Sie einfach die Antwort von @Gal Rom, behalten Sie einfach die vertikalen und horizontalen Deltas im Auge, und mit ein wenig Mathematik können Sie bestimmen, welche Art von Wischen ein touchEvent war. (Lassen Sie mich noch einmal betonen, dass dies OBSENELY auf einer früheren Antwort beruhte, aber die Einfachheit mag Anfänger ansprechen). Die Idee ist, einen OnTouchListener zu erweitern, zu erkennen, welche Art von Wischen (Berühren) gerade passiert ist, und für jede Art bestimmte Methoden aufzurufen.

public class SwipeListener implements View.OnTouchListener {
    private int min_distance = 100;
    private float downX, downY, upX, upY;
    View v;

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        this.v = v;
        switch(event.getAction()) { // Check vertical and horizontal touches
            case MotionEvent.ACTION_DOWN: {
                downX = event.getX();
                downY = event.getY();
                return true;
            }
            case MotionEvent.ACTION_UP: {
                upX = event.getX();
                upY = event.getY();

                float deltaX = downX - upX;
                float deltaY = downY - upY;

                //HORIZONTAL SCROLL
                if (Math.abs(deltaX) > Math.abs(deltaY)) {
                    if (Math.abs(deltaX) > min_distance) {
                        // left or right
                        if (deltaX < 0) {
                            this.onLeftToRightSwipe();
                            return true;
                        }
                        if (deltaX > 0) {
                            this.onRightToLeftSwipe();
                            return true;
                        }
                    } else {
                        //not long enough swipe...
                        return false;
                    }
                }
                //VERTICAL SCROLL
                else {
                    if (Math.abs(deltaY) > min_distance) {
                        // top or down
                        if (deltaY < 0) {
                            this.onTopToBottomSwipe();
                            return true;
                        }
                        if (deltaY > 0) {
                            this.onBottomToTopSwipe();
                            return true;
                        }
                    } else {
                        //not long enough swipe...
                        return false;
                    }
                }
                return false;
            }
        }
        return false;
    }

    public void onLeftToRightSwipe(){
        Toast.makeText(v.getContext(),"left to right",   
                                      Toast.LENGTH_SHORT).show();
    }

    public void onRightToLeftSwipe() {
        Toast.makeText(v.getContext(),"right to left",
                                     Toast.LENGTH_SHORT).show();
    }

    public void onTopToBottomSwipe() {
        Toast.makeText(v.getContext(),"top to bottom", 
                                     Toast.LENGTH_SHORT).show();
    }

    public void onBottomToTopSwipe() {
        Toast.makeText(v.getContext(),"bottom to top", 
                                    Toast.LENGTH_SHORT).show();
    }
}
Fiacobelli
quelle
3

Ich habe eine einfache Klasse geschrieben, die es einfach macht, die Swipe-Ereignisse zu erkennen - TOP, RIGHT, BOTTOM, LEFT.

1: Einzelne Wischereignisse erkennen

// Detect and consume specific events
// {Available methods} - detectTop, detectRight, detectBottom, detectLeft
SwipeEvents.detectTop(swipeElement, new SwipeEvents.SwipeSingleCallback() {
    @Override
    public void onSwipe() {
        showToast("Swiped - detectTop");
    }
});

2: Erkennen Sie eines der Swipe-Ereignisse mit einem Rückruf.

SwipeEvents.detect( swipeElement, new SwipeEvents.SwipeCallback() {
    @Override
    public void onSwipeTop() {
        //Swiped top
    }

    @Override
    public void onSwipeRight() {
        //Swiped right
    }

    @Override
    public void onSwipeBottom() {
        //Swiped bottom
    }

    @Override
    public void onSwipeLeft() {
        //Swiped left
    }
});

Hier ist ein Blog-Beitrag mit Erläuterungen zur Verwendung: http://bmutinda.com/android-detect-swipe-events/

Ich habe auch eine Übersicht für die hier verfügbaren Codefragmente erstellt: https://gist.github.com/bmutinda/9578f70f1df9bd0687b8

Vielen Dank.

Mutinda Boniface
quelle
3

Swipe Detector von links nach rechts und von rechts nach links

Deklarieren Sie zunächst zwei Variablen des Datentyps float.

private float x1, x2;

Zweitens verdrahten Sie Ihre XML-Ansicht in Java. Wie ich habeImageView

ImageView img = (ImageView) findViewById(R.id.imageView);

Drittens setOnTouchListenerauf Ihre ImageView.

img.setOnTouchListener(
                    new View.OnTouchListener() {
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        // TODO Auto-generated method stub
                        switch (event.getAction()) {
                        case MotionEvent.ACTION_DOWN:
                            x1 = event.getX();
                            break;
                        case MotionEvent.ACTION_UP:
                            x2 = event.getX();
                            float deltaX = x2 - x1;
                            if (deltaX < 0) {
                                Toast.makeText(MainActivity.this,
                                        "Right to Left swipe",
                                        Toast.LENGTH_SHORT).show();
                            }else if(deltaX >0){
                                Toast.makeText(MainActivity.this,
                                        "Left to Right swipe",
                                        Toast.LENGTH_SHORT).show();
                            }
                            break;
                        }

                        return false;
                    }
                });
Chintan Bawa
quelle
3

Ich möchte die akzeptierte Antwort ergänzen, die teilweise funktioniert, aber die Zeitvariable fehlt, die sie perfekt macht.

Einfachster Wischdetektor von links nach rechts mit einer Zeitvariablen:

Fügen Sie in Ihrer Aktivitätsklasse folgende Attribute hinzu:

private float x1,x2;
private long startClickTime;
static final int MIN_DISTANCE = 150;
static final int MAX_SWIPE_TIME = 200;

und überschreiben Sie die onTouchEvent () -Methode:

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        switch(event.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                startClickTime = Calendar.getInstance().getTimeInMillis();
                x1 = event.getX();
                break;
            case MotionEvent.ACTION_UP:
                long clickDuration = Calendar.getInstance().getTimeInMillis() - startClickTime;
                x2 = event.getX();
                float deltaX = x2 - x1;
                if (Math.abs(deltaX) > MIN_DISTANCE && clickDuration < MAX_SWIPE_TIME)
                {
                    Toast.makeText(this, "left2right swipe", Toast.LENGTH_SHORT).show ();
                }
                else
                {
                    // consider as something else - a screen tap for example
                }
                break;
        }
        return super.onTouchEvent(event);
    }
Dangalg
quelle
3

Ich denke, was du willst, heißt Fling. Die MotionEvents können verwendet werden, um die Richtung des Schleuderns zu bestimmen.

public class MainActivity extends Activity implements  GestureDetector.OnGestureListener {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.stellar_layout);
        mDetector = new GestureDetectorCompat(this, this);
    }

    @Override
    public boolean onFling(MotionEvent event1, MotionEvent event2,
                           float velocityX, float velocityY) {
        Log.d(tag, "onFling:\n " + event1.toString()+ "\n " + event2.toString());
        /* prints the following
            MotionEvent { action=ACTION_DOWN, id[0]=0, x[0]=297.0, y[0]=672.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=488341979, downTime=488341979, deviceId=6, source=0x1002 }
            MotionEvent { action=ACTION_UP, id[0]=0, x[0]=560.0, y[0]=583.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=488342047, downTime=488341979, deviceId=6, source=0x1002 }
        */
        return true;
    }

}

http://developer.android.com/training/gestures/detector.html

activedecay
quelle
2

Erkennen Sie das Streichen in vier Richtungen

private float x1,x2,y1,y2;
static final int MIN_DISTANCE = 70;

und

switch(pSceneTouchEvent.getAction())
     {
       case MotionEvent.ACTION_DOWN:
           x1 = pSceneTouchEvent.getX();     
           y1 = pSceneTouchEvent.getY();
       break;         
       case MotionEvent.ACTION_UP:
           x2 = pSceneTouchEvent.getX();
           y2 = pSceneTouchEvent.getY();
           float deltaX = x2 - x1;
           float deltaY = y2 - y1;
           if (deltaX > MIN_DISTANCE)
           {
               swipeLeftToRight();
           }
           else if( Math.abs(deltaX) > MIN_DISTANCE)
           {
               swipeRightToLeft();
           } 
           else if(deltaY > MIN_DISTANCE){
               swipeTopToBottom();
           } 
           else if( Math.abs(deltaY) > MIN_DISTANCE){
               swipeBottopmToTop();
           }

       break;   
     }          
Manian Rezaee
quelle
2

Nach einem ganzen Tag Arbeit an dieser Funktion kann man endlich die richtige Antwort bekommen.

Erstellen Sie zunächst die folgenden Klassen:

import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

/**
 * Created by hoshyar on 1/19/17.
 */

public class SwipeDetector implements View.OnTouchListener {

    public static enum Action {
        LR, // Left to Right
        RL, // Right to Left
        TB, // Top to bottom
        BT, // Bottom to Top
        None // when no action was detected
    }

    private static final String logTag = "Swipe";
    private static final int MIN_DISTANCE = 100;
    private float downX, downY, upX, upY;
    private Action mSwipeDetected = Action.None;

    public boolean swipeDetected() {
        return mSwipeDetected != Action.None;
    }

    public Action getAction() {
        return mSwipeDetected;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX = event.getX();
                downY = event.getY();
                mSwipeDetected = Action.None;
                return false;

            case MotionEvent.ACTION_MOVE:
                upX = event.getX();
                upY = event.getY();

                float deltaX = downX - upX;
                float deltaY = downY - upY;
                Log.i(logTag,String.valueOf(deltaX));
                Log.i(logTag,String.valueOf(deltaX));

                if (deltaY>0 && deltaY<10 && deltaX<0 || deltaY==0 && deltaX>-15 && deltaX<0){
                    Log.i(logTag,"to right");
                }if (deltaY>=0 && deltaY<10 && deltaX>0 || deltaY<0 && deltaX>15 && deltaX<40){
                Log.i(logTag,"to left");
            }





                if (Math.abs(deltaX) > MIN_DISTANCE) {
                    // left or right
                    if (deltaX < 0) {
                        mSwipeDetected = Action.LR;
                        return false;
                    }
                    if (deltaX > 0) {


                        mSwipeDetected = Action.RL;
                        return false;
                    }
                } else if (Math.abs(deltaY) > MIN_DISTANCE) {


                    if (deltaY < 0) {
                        Log.i(logTag,"to bottom");
                        mSwipeDetected = Action.TB;
                        return false;
                    }
                    if (deltaY > 0) {
                        Log.i(logTag,"to up");
                        mSwipeDetected = Action.BT;
                        return false;
                    }
                }
                return true;
        }
        return false;
    }
}

Schließlich auf das Objekt, das Sie anwenden möchten. Mein Beispiel:

SwipeDetector swipeDetector = new SwipeDetector();
listView.setOnTouchListener(swipeDetector);

Viel Glück .

HOSHYAR Ahmadpour
quelle
aber wie kann man das Ereignis an die Klasse zurückgeben?
Vivek
1

Wenn Sie das Ereignis vom Beginn des Wischens an abfangen möchten, können Sie MotionEvent.ACTION_MOVE verwenden und den ersten zu vergleichenden Wert speichern

private float upX1;
private float upX2;
private float upY1;
private float upY2;
private boolean isTouchCaptured = false;
static final int min_distance = 100;


        viewObject.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_MOVE: {
                        downX = event.getX();
                        downY = event.getY();

                        if (!isTouchCaptured) {
                            upX1 = event.getX();
                            upY1 = event.getY();
                            isTouchCaptured = true;
                        } else {
                            upX2 = event.getX();
                            upY2 = event.getY();

                            float deltaX = upX1 - upX2;
                            float deltaY = upY1 - upY2;
                            //HORIZONTAL SCROLL
                            if (Math.abs(deltaX) > Math.abs(deltaY)) {
                                if (Math.abs(deltaX) > min_distance) {
                                    // left or right
                                    if (deltaX < 0) {

                                        return true;
                                    }
                                    if (deltaX > 0) {
                                        return true;
                                    }
                                } else {
                                    //not long enough swipe...
                                    return false;
                                }
                            }
                            //VERTICAL SCROLL
                            else {
                                if (Math.abs(deltaY) > min_distance) {
                                    // top or down
                                    if (deltaY < 0) {

                                        return false;
                                    }
                                    if (deltaY > 0) {

                                        return false;
                                    }
                                } else {
                                    //not long enough swipe...
                                    return false;
                                }
                            }
                        }
                        return false;
                    }
                    case MotionEvent.ACTION_UP: {
                        isTouchCaptured = false;
                    }
                }
                return false;

            }
        });
Vendras Panagiotis
quelle
Nehmen wir an, ich habe einen Toast wie Toast.makeText(MainAcivity.this, "top to down" + increaseValue, Toast.LENGTH_SHORT).show();sie. Wie mache ich einen einzelnen Schlag, um die Werte min = 0 und max = 10 hinzuzufügen?
Sanoj Lawrence
1

das sollte dir vielleicht helfen ...

private final GestureDetector.SimpleOnGestureListener onGestureListener = new GestureDetector.SimpleOnGestureListener() {
    @Override
    public boolean onDoubleTap(MotionEvent e) {
        Log.i("gestureDebug333", "doubleTapped:" + e);
        return super.onDoubleTap(e);
    }

    @Override
    public boolean onDoubleTapEvent(MotionEvent e) {
        Log.i("gestureDebug333", "doubleTappedEvent:" + e);

        return super.onDoubleTapEvent(e);
    }

    @Override
    public boolean onDown(MotionEvent e) {
        Log.i("gestureDebug333", "onDown:" + e);


        return super.onDown(e);

    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {


        Log.i("gestureDebug333", "flinged:" + e1 + "---" + e2);
        Log.i("gestureDebug333", "fling velocity:" + velocityX + "---" + velocityY);
        if (e1.getAction() == MotionEvent.ACTION_DOWN && e1.getX() > (e2.getX() + 300)){
           // Toast.makeText(context, "flinged right to left", Toast.LENGTH_SHORT).show();
            goForward();
        }
        if (e1.getAction() == MotionEvent.ACTION_DOWN && e2.getX() > (e1.getX() + 300)){
            //Toast.makeText(context, "flinged left to right", Toast.LENGTH_SHORT).show();
            goBack();
        }
        return super.onFling(e1, e2, velocityX, velocityY);
    }

    @Override
    public void onLongPress(MotionEvent e) {
        super.onLongPress(e);
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        return super.onScroll(e1, e2, distanceX, distanceY);
    }

    @Override
    public void onShowPress(MotionEvent e) {
        super.onShowPress(e);
    }

    @Override
    public boolean onSingleTapConfirmed(MotionEvent e) {
        return super.onSingleTapConfirmed(e);
    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        return super.onSingleTapUp(e);
    }
};
Liron Navon
quelle
1

Kurze und einfache Version:

1. Erstellen Sie zuerst diese abstrakte Klasse

public abstract class HorizontalSwipeListener implements View.OnTouchListener {

    private float firstX;
    private int minDistance;

    HorizontalSwipeListener(int minDistance) {
        this.minDistance = minDistance;
    }

    abstract void onSwipeRight();

    abstract void onSwipeLeft();

    @Override
    public boolean onTouch(View view, MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                firstX = event.getX();
                return true;
            case MotionEvent.ACTION_UP:
                float secondX = event.getX();
                if (Math.abs(secondX - firstX) > minDistance) {
                    if (secondX > firstX) {
                        onSwipeLeft();
                    } else {
                        onSwipeRight();
                    }
                }
                return true;
        }
        return view.performClick();
    }

}

2. Erstellen Sie dann eine konkrete Klasse, die implementiert, was Sie benötigen:

public class SwipeListener extends HorizontalSwipeListener {

    public SwipeListener() {
        super(200);
    }

    @Override
    void onSwipeRight() {
        System.out.println("right");
    }

    @Override
    void onSwipeLeft() {
        System.out.println("left");
    }

}
Topera
quelle
1

Hier ist ein generischer Swipe-Left-Detektor für jede Ansicht in Kotlin mithilfe der Datenbindung

@BindingAdapter("onSwipeLeft")
fun View.setOnSwipeLeft(runnable: Runnable) {
    setOnTouchListener(object : View.OnTouchListener {
        var x0 = 0F; var y0 = 0F; var t0 = 0L
        val defaultClickDuration = 200

        override fun onTouch(v: View?, motionEvent: MotionEvent?): Boolean {
            motionEvent?.let { event ->
                when(event.action) {
                    MotionEvent.ACTION_DOWN -> {
                        x0 = event.x; y0 = event.y; t0 = System.currentTimeMillis()
                    }
                    MotionEvent.ACTION_UP -> {
                        val x1 = event.x; val y1 = event.y; val t1 = System.currentTimeMillis()

                        if (x0 == x1 && y0 == y1 && (t1 - t0) < defaultClickDuration) {
                            performClick()
                            return false
                        }
                        if (x0 > x1) { runnable.run() }
                    }
                    else -> {}
                }
            }
            return true
        }
    })
}

und dann, um es in Ihrem Layout zu verwenden:

app:onSwipeLeft="@{() -> viewModel.swipeLeftHandler()}"
Raphael C.
quelle
0
public class TransferMarket extends Activity {

    float x1,x2;
    float y1, y2;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_transfer_market);
    }

    // onTouchEvent () method gets called when User performs any touch event on screen

    // Method to handle touch event like left to right swap and right to left swap

    public boolean onTouchEvent(MotionEvent touchevent)
    {
        switch (touchevent.getAction())
        {
            // when user first touches the screen we get x and y coordinate
            case MotionEvent.ACTION_DOWN:
            {
                x1 = touchevent.getX();
                y1 = touchevent.getY();
                break;
            }
            case MotionEvent.ACTION_UP:
            {
                x2 = touchevent.getX();
                y2 = touchevent.getY();

                //if left to right sweep event on screen
                if (x1 < x2)
                {
                    Toast.makeText(this, "Left to Right Swap Performed", Toast.LENGTH_LONG).show();
                }

                // if right to left sweep event on screen
                if (x1 > x2)
                {
                    Toast.makeText(this, "Right to Left Swap Performed", Toast.LENGTH_LONG).show();
                }

                // if UP to Down sweep event on screen
                if (y1 < y2)
                {
                    Toast.makeText(this, "UP to Down Swap Performed", Toast.LENGTH_LONG).show();
                }

                //if Down to UP sweep event on screen
                if (y1 > y2)
                {
                    Toast.makeText(this, "Down to UP Swap Performed", Toast.LENGTH_LONG).show();
                }
                break;
            }
        }
        return false;
    }
Syed Atir Mohiuddin
quelle
Verwenden Sie nur x-Koordinaten, die für von links nach rechts und umgekehrt ausreichen
Abhishek
0

Die beste Antwort ist @Gal Roms. Es gibt weitere Informationen dazu: Berühren Sie das Ereignis, um zuerst zu den untergeordneten Ansichten zurückzukehren. und wenn Sie für sie den onClick- oder onTouch-Listener definieren, erhält die parnt-Ansicht (z. B. Fragment) keinen Touch-Listener. Wenn Sie in dieser Situation den Swipe-Listener für Fragment definieren möchten, müssen Sie ihn in einer neuen Klasse implementieren:

    package com.neganet.QRelations.fragments;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.FrameLayout;

public class SwipeListenerFragment extends FrameLayout {
    private float x1,x2;
    static final int MIN_DISTANCE=150;
    private onSwipeEventDetected mSwipeDetectedListener;


    public SwipeListenerFragment(Context context) {
        super(context);
    }

    public SwipeListenerFragment(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SwipeListenerFragment(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        boolean result=false;
        switch(ev.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                x1 = ev.getX();
                break;
            case MotionEvent.ACTION_UP:
                x2 = ev.getX();
                float deltaX = x2 - x1;
                if (Math.abs(deltaX) > MIN_DISTANCE)
                {
                    if(deltaX<0)
                    {
                        result=true;
                        if(mSwipeDetectedListener!=null)
                            mSwipeDetectedListener.swipeLeftDetected();

                    }else if(deltaX>0){
                        result=true;
                        if(mSwipeDetectedListener!=null)
                            mSwipeDetectedListener.swipeRightDetected();
                    }
                }
                break;
        }
        return result;
    }

    public interface onSwipeEventDetected
    {
        public void swipeLeftDetected();
        public void swipeRightDetected();

    }

    public void registerToSwipeEvents(onSwipeEventDetected listener)
    {
        this.mSwipeDetectedListener=listener;
    }
}

Ich habe die Klasse von @Gal Rom geändert. So kann es sowohl das Wischen nach rechts als auch nach links erkennen und gibt nach dem Erkennen onInterceptTouchEvent true zurück. Dies ist wichtig, da untergeordnete Ansichten möglicherweise ein Ereignis erhalten, wenn wir dies manchmal nicht tun, und sowohl Swipe für Fragment als auch onClick für untergeordnete Ansicht (zum Beispiel) ausgeführt werden und einige Probleme verursachen. Nachdem Sie diese Klasse erstellt haben, müssen Sie Ihre Fragment-XML-Datei ändern:

    <com.neganet.QRelations.fragments.SwipeListenerFragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:id="@+id/main_list_layout"
    android:clickable="true"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:layout_height="match_parent" tools:context="com.neganet.QRelations.fragments.mainList"
    android:background="@color/main_frag_back">

    <!-- TODO: Update blank fragment layout -->
    <android.support.v7.widget.RecyclerView
        android:id="@+id/farazList"
        android:scrollbars="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="left|center_vertical" />
</com.neganet.QRelations.fragments.SwipeListenerFragment>

Sie sehen, dass das begin-Tag die Klasse ist, die wir erstellt haben. jetzt in Fragmentklasse:

            View view=inflater.inflate(R.layout.fragment_main_list, container, false);
        SwipeListenerFragment tdView=(SwipeListenerFragment) view;
        tdView.registerToSwipeEvents(this);


and then Implement SwipeListenerFragment.onSwipeEventDetected in it:

        @Override
    public void swipeLeftDetected() {
        Toast.makeText(getActivity(), "left", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void swipeRightDetected() {
        Toast.makeText(getActivity(), "right", Toast.LENGTH_SHORT).show();
    }

Es ist etwas kompliziert, funktioniert aber perfekt :)

Solivan
quelle
0

Sie sollten eine Klasse aus erweitern View.OnTouchListenerund die onTouchMethode behandeln, indem Sie sie überschreiben.

interface SwipeListener {
    fun onSwipeLeft()
    fun onSwipeRight()
}

class SwipeGestureListener internal constructor(
    private val listener: SwipeListener,
    private val minDistance: Int = DEFAULT_SWIPE_MIN_DISTANCE
) : View.OnTouchListener {
    companion object {
        const val DEFAULT_SWIPE_MIN_DISTANCE = 200
    }

    private var anchorX = 0F

    override fun onTouch(view: View, event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                anchorX = event.x
                return true
            }
            MotionEvent.ACTION_UP -> {
                if (abs(event.x - anchorX) > minDistance) {
                    if (event.x > anchorX) {
                        listener.onSwipeRight()
                    } else {
                        listener.onSwipeLeft()
                    }
                }
                return true
            }
        }
        return view.performClick()
    }
}

Sie können es einfach so in Ihrem Activityoder implementieren Fragment.

class MainActivity : AppCompatActivity(), SwipeListener {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        viewGroup.setOnTouchListener(SwipeGestureListener(this))
    }

    override fun onSwipeLeft() {
        Toast.makeText(this, "Swipe Left", Toast.LENGTH_SHORT).show()
    }

    override fun onSwipeRight() {
        Toast.makeText(this, "Swipe Right", Toast.LENGTH_SHORT).show()
    }
}
Morgan Koh
quelle