Android: hoe om te gaan met veegbewegingen van rechts naar links

Ik wil dat mijn app herkent wanneer een gebruiker van rechts naar links veegt op het telefoonscherm.

Hoe doe je dit?


Antwoord 1, autoriteit 100%

OnSwipeTouchListener.java:

import android.content.Context;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
public class OnSwipeTouchListener implements OnTouchListener {
    private final GestureDetector gestureDetector;
    public OnSwipeTouchListener (Context ctx){
        gestureDetector = new GestureDetector(ctx, new GestureListener());
    }
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
    }
    private final class GestureListener extends 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) {
                            onSwipeRight();
                        } else {
                            onSwipeLeft();
                        }
                        result = true;
                    }
                }
                else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffY > 0) {
                        onSwipeBottom();
                    } else {
                        onSwipeTop();
                    }
                    result = true;
                }
            } catch (Exception exception) {
                exception.printStackTrace();
            }
            return result;
        }
    }
    public void onSwipeRight() {
    }
    public void onSwipeLeft() {
    }
    public void onSwipeTop() {
    }
    public void onSwipeBottom() {
    }
}

Gebruik:

imageView.setOnTouchListener(new OnSwipeTouchListener(MyActivity.this) {
    public void onSwipeTop() {
        Toast.makeText(MyActivity.this, "top", Toast.LENGTH_SHORT).show();
    }
    public void onSwipeRight() {
        Toast.makeText(MyActivity.this, "right", Toast.LENGTH_SHORT).show();
    }
    public void onSwipeLeft() {
        Toast.makeText(MyActivity.this, "left", Toast.LENGTH_SHORT).show();
    }
    public void onSwipeBottom() {
        Toast.makeText(MyActivity.this, "bottom", Toast.LENGTH_SHORT).show();
    }
});

Antwoord 2, autoriteit 24%

Deze code detecteert veegbewegingen naar links en rechts, vermijdt verouderde API-aanroepen en heeft andere diverse verbeteringen ten opzichte van eerdere antwoorden.

/**
 * Detects left and right swipes across a view.
 */
public class OnSwipeTouchListener implements OnTouchListener {
    private final GestureDetector gestureDetector;
    public OnSwipeTouchListener(Context context) {
        gestureDetector = new GestureDetector(context, new GestureListener());
    }
    public void onSwipeLeft() {
    }
    public void onSwipeRight() {
    }
    public boolean onTouch(View v, MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
    }
    private final class GestureListener extends SimpleOnGestureListener {
        private static final int SWIPE_DISTANCE_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) {
            float distanceX = e2.getX() - e1.getX();
            float distanceY = e2.getY() - e1.getY();
            if (Math.abs(distanceX) > Math.abs(distanceY) && Math.abs(distanceX) > SWIPE_DISTANCE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                if (distanceX > 0)
                    onSwipeRight();
                else
                    onSwipeLeft();
                return true;
            }
            return false;
        }
    }
}

Gebruik het als volgt:

view.setOnTouchListener(new OnSwipeTouchListener(context) {
    @Override
    public void onSwipeLeft() {
        // Whatever
    }
});

Antwoord 3, autoriteit 6%

Als u ook klikgebeurtenissen moet verwerken, hier enkele wijzigingen:

public class OnSwipeTouchListener implements OnTouchListener {
    private final GestureDetector gestureDetector = new GestureDetector(new GestureListener());
    public boolean onTouch(final View v, final MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
    }
    private final class GestureListener extends SimpleOnGestureListener {
        private static final int SWIPE_THRESHOLD = 100;
        private static final int SWIPE_VELOCITY_THRESHOLD = 100;
        @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 {
                    if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffY > 0) {
                            result = onSwipeBottom();
                        } else {
                            result = onSwipeTop();
                        }
                    }
                }
            } catch (Exception exception) {
                exception.printStackTrace();
            }
            return result;
        }
    }
    public boolean onSwipeRight() {
        return false;
    }
    public boolean onSwipeLeft() {
        return false;
    }
    public boolean onSwipeTop() {
        return false;
    }
    public boolean onSwipeBottom() {
        return false;
    }
}

En voorbeeldgebruik:

   background.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View arg0) {
            toggleSomething();
        }
    });
    background.setOnTouchListener(new OnSwipeTouchListener() {
        public boolean onSwipeTop() {
            Toast.makeText(MainActivity.this, "top", Toast.LENGTH_SHORT).show();
            return true;
        }
        public boolean onSwipeRight() {
            Toast.makeText(MainActivity.this, "right", Toast.LENGTH_SHORT).show();
            return true;
        }
        public boolean onSwipeLeft() {
            Toast.makeText(MainActivity.this, "left", Toast.LENGTH_SHORT).show();
            return true;
        }
        public boolean onSwipeBottom() {
            Toast.makeText(MainActivity.this, "bottom", Toast.LENGTH_SHORT).show();
            return true;
        }
    });

Antwoord 4, autoriteit 4%

Uitbreiding van Mireks antwoord, voor het geval je de veegbewegingen in een scrollweergave wilt gebruiken. Standaard wordt de aanraaklistener voor de schuifweergave uitgeschakeld en daarom vindt er geen schuifactie plaats. Om dit op te lossen moet je de dispatchTouchEventmethode van de Activityoverschrijven en de overgenomen versie van deze methode teruggeven nadat je klaar bent met je eigen luisteraar.

Om een ​​paar wijzigingen aan de Mirek-code aan te brengen:
Ik voeg een getter toe voor de GestureDetectorin de OnSwipeTouchListener.

public GestureDetector getGestureDetector(){
    return  gestureDetector;
}

Declareer de OnSwipeTouchListenerin de activiteit als een klassebreed veld.

OnSwipeTouchListener onSwipeTouchListener;

Wijzig de gebruikscode dienovereenkomstig:

onSwipeTouchListener = new OnSwipeTouchListener(MyActivity.this) {
    public void onSwipeTop() {
        Toast.makeText(MyActivity.this, "top", Toast.LENGTH_SHORT).show();
    }
    public void onSwipeRight() {
        Toast.makeText(MyActivity.this, "right", Toast.LENGTH_SHORT).show();
    }
    public void onSwipeLeft() {
        Toast.makeText(MyActivity.this, "left", Toast.LENGTH_SHORT).show();
    }
    public void onSwipeBottom() {
        Toast.makeText(MyActivity.this, "bottom", Toast.LENGTH_SHORT).show();
    }
});
imageView.setOnTouchListener(onSwipeTouchListener);

En overschrijf de dispatchTouchEventmethode binnen Activity:

@Override
    public boolean dispatchTouchEvent(MotionEvent ev){
        swipeListener.getGestureDetector().onTouchEvent(ev); 
            return super.dispatchTouchEvent(ev);   
    }

Nu zouden zowel scroll- als veegacties moeten werken.


Antwoord 5, autoriteit 3%

Om Click Listener, DoubleClick Listener, OnLongPress Listener, Swipe Left, Swipe Right, Swipe Up, Swipe Downop één Viewdie je moet setOnTouchListener. d.w.z.

view.setOnTouchListener(new OnSwipeTouchListener(MainActivity.this) {
            @Override
            public void onClick() {
                super.onClick();
                // your on click here
            }
            @Override
            public void onDoubleClick() {
                super.onDoubleClick();
                // your on onDoubleClick here
            }
            @Override
            public void onLongClick() {
                super.onLongClick();
                // your on onLongClick here
            }
            @Override
            public void onSwipeUp() {
                super.onSwipeUp();
                // your swipe up here
            }
            @Override
            public void onSwipeDown() {
                super.onSwipeDown();
                // your swipe down here.
            }
            @Override
            public void onSwipeLeft() {
                super.onSwipeLeft();
                // your swipe left here.
            }
            @Override
            public void onSwipeRight() {
                super.onSwipeRight();
                // your swipe right here.
            }
        });
}

Hiervoor heb je de klasse OnSwipeTouchListenernodig die OnTouchListenerimplementeert.

public class OnSwipeTouchListener implements View.OnTouchListener {
private GestureDetector gestureDetector;
public OnSwipeTouchListener(Context c) {
    gestureDetector = new GestureDetector(c, new GestureListener());
}
public boolean onTouch(final View view, final MotionEvent motionEvent) {
    return gestureDetector.onTouchEvent(motionEvent);
}
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 onSingleTapUp(MotionEvent e) {
        onClick();
        return super.onSingleTapUp(e);
    }
    @Override
    public boolean onDoubleTap(MotionEvent e) {
        onDoubleClick();
        return super.onDoubleTap(e);
    }
    @Override
    public void onLongPress(MotionEvent e) {
        onLongClick();
        super.onLongPress(e);
    }
    // Determines the fling velocity and then fires the appropriate swipe event accordingly
    @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) {
                        onSwipeRight();
                    } else {
                        onSwipeLeft();
                    }
                }
            } else {
                if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffY > 0) {
                        onSwipeDown();
                    } else {
                        onSwipeUp();
                    }
                }
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return result;
    }
}
public void onSwipeRight() {
}
public void onSwipeLeft() {
}
public void onSwipeUp() {
}
public void onSwipeDown() {
}
public void onClick() {
}
public void onDoubleClick() {
}
public void onLongClick() {
}
}

Antwoord 6, autoriteit 2%

Kotlin-versie van @Mirek Rusin is hier:

OnSwipeTouchListener.kt :

open class OnSwipeTouchListener(ctx: Context) : OnTouchListener {
    private val gestureDetector: GestureDetector
    companion object {
        private val SWIPE_THRESHOLD = 100
        private val SWIPE_VELOCITY_THRESHOLD = 100
    }
    init {
        gestureDetector = GestureDetector(ctx, GestureListener())
    }
    override fun onTouch(v: View, event: MotionEvent): Boolean {
        return gestureDetector.onTouchEvent(event)
    }
    private inner class GestureListener : SimpleOnGestureListener() {
        override fun onDown(e: MotionEvent): Boolean {
            return true
        }
        override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
            var result = false
            try {
                val diffY = e2.y - e1.y
                val diffX = e2.x - e1.x
                if (Math.abs(diffX) > Math.abs(diffY)) {
                    if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffX > 0) {
                            onSwipeRight()
                        } else {
                            onSwipeLeft()
                        }
                        result = true
                    }
                } else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffY > 0) {
                        onSwipeBottom()
                    } else {
                        onSwipeTop()
                    }
                    result = true
                }
            } catch (exception: Exception) {
                exception.printStackTrace()
            }
            return result
        }
    }
    open fun onSwipeRight() {}
    open fun onSwipeLeft() {}
    open fun onSwipeTop() {}
    open fun onSwipeBottom() {}
}

Gebruik:

view.setOnTouchListener(object : OnSwipeTouchListener(context) {
    override fun onSwipeTop() {
        super.onSwipeTop()
    }
    override fun onSwipeBottom() {
        super.onSwipeBottom()
    }
    override fun onSwipeLeft() {
        super.onSwipeLeft()
    }
    override fun onSwipeRight() {
        super.onSwipeRight()
    }
})

het openzoekwoord was het punt voor mij…


Antwoord 7, autoriteit 2%

Je hebt geen ingewikkelde berekeningen nodig.
Het kan alleen worden gedaan door de OnGestureListener-interface van de klasse GestureDetectorte gebruiken.

Binnen de onFlingmethode kun je alle vier de richtingen als volgt detecteren:

MyGestureListener.java:

import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
public class MyGestureListener implements GestureDetector.OnGestureListener{
    private static final long VELOCITY_THRESHOLD = 3000;
    @Override
    public boolean onDown(final MotionEvent e){ return false; }
    @Override
    public void onShowPress(final MotionEvent e){ }
    @Override
    public boolean onSingleTapUp(final MotionEvent e){ return false; }
    @Override
    public boolean onScroll(final MotionEvent e1, final MotionEvent e2, final float distanceX,
                        final float distanceY){ return false; }
    @Override
    public void onLongPress(final MotionEvent e){ }
    @Override
    public boolean onFling(final MotionEvent e1, final MotionEvent e2,
                       final float velocityX,
                       final float velocityY){
        if(Math.abs(velocityX) < VELOCITY_THRESHOLD 
                    && Math.abs(velocityY) < VELOCITY_THRESHOLD){
            return false;//if the fling is not fast enough then it's just like drag
        }
        //if velocity in X direction is higher than velocity in Y direction,
        //then the fling is horizontal, else->vertical
        if(Math.abs(velocityX) > Math.abs(velocityY)){
            if(velocityX >= 0){
                Log.i("TAG", "swipe right");
            }else{//if velocityX is negative, then it's towards left
                Log.i("TAG", "swipe left");
            }
        }else{
            if(velocityY >= 0){
                Log.i("TAG", "swipe down");
            }else{
                Log.i("TAG", "swipe up");
            }
        }
        return true;
    }
}

gebruik:

GestureDetector mDetector = new GestureDetector(MainActivity.this, new MyGestureListener());
view.setOnTouchListener(new View.OnTouchListener(){
    @Override
    public boolean onTouch(final View v, final MotionEvent event){
        return mDetector.onTouchEvent(event);
    }
});

Antwoord 8

Gebruik SwipeListViewen laat het de bewegingsdetectie voor je afhandelen.

Screenshot


Antwoord 9

Om ook een onClick toe te voegen, heb ik het volgende gedaan.

....
// in OnSwipeTouchListener class
private final class GestureListener extends SimpleOnGestureListener {
    .... // normal GestureListener  code
   @Override
    public boolean onSingleTapConfirmed(MotionEvent e) {
        onClick(); // my method
        return super.onSingleTapConfirmed(e);
    }
} // end GestureListener class
    public void onSwipeRight() {
    }
    public void onSwipeLeft() {
    }
    public void onSwipeTop() {
    }
    public void onSwipeBottom() {
    }
    public void onClick(){ 
    }
    // as normal
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
}
} // end OnSwipeTouchListener class

Ik gebruik fragmenten, dus ik gebruik getActivity() voor context. Dit is hoe ik het heb geïmplementeerd – en het werkt.


myLayout.setOnTouchListener(new OnSwipeTouchListener(getActivity()) {
            public void onSwipeTop() {
                Toast.makeText(getActivity(), "top", Toast.LENGTH_SHORT).show();
            }
            public void onSwipeRight() {
                Toast.makeText(getActivity(), "right", Toast.LENGTH_SHORT).show();
            }
            public void onSwipeLeft() {
                Toast.makeText(getActivity(), "left", Toast.LENGTH_SHORT).show();
            }
            public void onSwipeBottom() {
                Toast.makeText(getActivity(), "bottom", Toast.LENGTH_SHORT).show();
            }
            public void onClick(){
                Toast.makeText(getActivity(), "clicked", Toast.LENGTH_SHORT).show();
            }
        });

Antwoord 10

@Edward Brey’s methodewerkt prima. Als iemand ook & plak de import voor de OnSwipeTouchListener, hier zijn ze:

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

Antwoord 11

Mijn oplossing is vergelijkbaar met die hierboven, maar ik heb de bewegingsafhandeling geabstraheerd in een abstracte klasse OnGestureRegisterListener.java, inclusief swipe, kliken lange klikgebaren.

OnGestureRegisterListener.java

public abstract class OnGestureRegisterListener implements View.OnTouchListener {
    private final GestureDetector gestureDetector;
    private View view;
    public OnGestureRegisterListener(Context context) {
        gestureDetector = new GestureDetector(context, new GestureListener());
    }
    @Override
    public boolean onTouch(View view, MotionEvent event) {
        this.view = view;
        return gestureDetector.onTouchEvent(event);
    }
    public abstract void onSwipeRight(View view);
    public abstract void onSwipeLeft(View view);
    public abstract void onSwipeBottom(View view);
    public abstract void onSwipeTop(View view);
    public abstract void onClick(View view);
    public abstract boolean onLongClick(View view);
    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 void onLongPress(MotionEvent e) {
            onLongClick(view);
            super.onLongPress(e);
        }
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            onClick(view);
            return super.onSingleTapUp(e);
        }
        @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) {
                            onSwipeRight(view);
                        } else {
                            onSwipeLeft(view);
                        }
                        result = true;
                    }
                }
                else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffY > 0) {
                        onSwipeBottom(view);
                    } else {
                        onSwipeTop(view);
                    }
                    result = true;
                }
            } catch (Exception exception) {
                exception.printStackTrace();
            }
            return result;
        }
    }
}

En gebruik het zo. Merk op dat u ook gemakkelijk uw parameter Viewkunt invoeren.

OnGestureRegisterListener onGestureRegisterListener = new OnGestureRegisterListener(this) {
    public void onSwipeRight(View view) {
        // Do something
    }
    public void onSwipeLeft(View view) {
        // Do something
    }
    public void onSwipeBottom(View view) {
        // Do something
    }
    public void onSwipeTop(View view) {
        // Do something
    }
    public void onClick(View view) {
        // Do something
    }
    public boolean onLongClick(View view) { 
        // Do something
        return true;
    }
};
Button button = findViewById(R.id.my_button);
button.setOnTouchListener(onGestureRegisterListener);

Antwoord 12

Ik heb soortgelijke dingen gedaan, maar alleen voor horizontale veegbewegingen

import android.content.Context
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
abstract class OnHorizontalSwipeListener(val context: Context) : View.OnTouchListener {    
    companion object {
         const val SWIPE_MIN = 50
         const val SWIPE_VELOCITY_MIN = 100
    }
    private val detector = GestureDetector(context, GestureListener())
    override fun onTouch(view: View, event: MotionEvent) = detector.onTouchEvent(event)    
    abstract fun onRightSwipe()
    abstract fun onLeftSwipe()
    private inner class GestureListener : GestureDetector.SimpleOnGestureListener() {    
        override fun onDown(e: MotionEvent) = true
        override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float)
            : Boolean {
            val deltaY = e2.y - e1.y
            val deltaX = e2.x - e1.x
            if (Math.abs(deltaX) < Math.abs(deltaY)) return false
            if (Math.abs(deltaX) < SWIPE_MIN
                    && Math.abs(velocityX) < SWIPE_VELOCITY_MIN) return false
            if (deltaX > 0) onRightSwipe() else onLeftSwipe()
            return true
        }
    }
}

En dan kan het worden gebruikt voor weergavecomponenten

private fun listenHorizontalSwipe(view: View) {
    view.setOnTouchListener(object : OnHorizontalSwipeListener(context!!) {
            override fun onRightSwipe() {
                Log.d(TAG, "Swipe right")
            }
            override fun onLeftSwipe() {
                Log.d(TAG, "Swipe left")
            }
        }
    )
}

Antwoord 13

Een kleine wijziging van het antwoord van @Mirek Rusin en nu kun je multitouch-veegbewegingen detecteren. Deze code staat op Kotlin:

class OnSwipeTouchListener(ctx: Context, val onGesture: (gestureCode: Int) -> Unit) : OnTouchListener {
private val SWIPE_THRESHOLD = 200
private val SWIPE_VELOCITY_THRESHOLD = 200
private val gestureDetector: GestureDetector
var fingersCount = 0
fun resetFingers() {
    fingersCount = 0
}
init {
    gestureDetector = GestureDetector(ctx, GestureListener())
}
override fun onTouch(v: View, event: MotionEvent): Boolean {
    if (event.pointerCount > fingersCount) {
        fingersCount = event.pointerCount
    }
    return gestureDetector.onTouchEvent(event)
}
private inner class GestureListener : SimpleOnGestureListener() {
    override fun onDown(e: MotionEvent): Boolean {
        return true
    }
    override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
        var result = false
        try {
            val diffY = e2.y - e1.y
            val diffX = e2.x - e1.x
            if (Math.abs(diffX) > Math.abs(diffY)) {
                if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffX > 0) {
                        val gesture = when (fingersCount) {
                            1 -> Gesture.SWIPE_RIGHT
                            2 -> Gesture.TWO_FINGER_SWIPE_RIGHT
                            3 -> Gesture.THREE_FINGER_SWIPE_RIGHT
                            else -> -1
                        }
                        if (gesture > 0) {
                            onGesture.invoke(gesture)
                        }
                    } else {
                        val gesture = when (fingersCount) {
                            1 -> Gesture.SWIPE_LEFT
                            2 -> Gesture.TWO_FINGER_SWIPE_LEFT
                            3 -> Gesture.THREE_FINGER_SWIPE_LEFT
                            else -> -1
                        }
                        if (gesture > 0) {
                            onGesture.invoke(gesture)
                        }
                    }
                    resetFingers()
                }
            } else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                if (diffY > 0) {
                    val gesture = when (fingersCount) {
                        1 ->  Gesture.SWIPE_DOWN
                        2 -> Gesture.TWO_FINGER_SWIPE_DOWN
                        3 -> Gesture.THREE_FINGER_SWIPE_DOWN
                        else -> -1
                    }
                    if (gesture > 0) {
                        onGesture.invoke(gesture)
                    }
                } else {
                    val gesture = when (fingersCount) {
                        1 ->  Gesture.SWIPE_UP
                        2 -> Gesture.TWO_FINGER_SWIPE_UP
                        3 -> Gesture.THREE_FINGER_SWIPE_UP
                        else -> -1
                    }
                    if (gesture > 0) {
                        onGesture.invoke(gesture)
                    }
                }
                resetFingers()
            }
            result = true
        } catch (exception: Exception) {
            exception.printStackTrace()
        }
        return result
    }
}}

Waar Gesture.SWIPE_RIGHT en anderen een unieke integer-identificator zijn van gebaren die ik gebruik om later in mijn activiteit een soort gebaar te detecteren:

rootView?.setOnTouchListener(OnSwipeTouchListener(this, {
    gesture -> log(Gesture.parseName(this, gesture))
}))

Dus je ziet dat het gebaar hier een integer-variabele is met een waarde die ik eerder heb doorgegeven.


Antwoord 14

Deze vraag is vele jaren geleden gesteld. Nu is er een betere oplossing: SmartSwipe: https://github.com/luckybilly/SmartSwipe

code ziet er als volgt uit:

SmartSwipe.wrap(contentView)
        .addConsumer(new StayConsumer()) //contentView stay while swiping with StayConsumer
        .enableAllDirections() //enable directions as needed
        .addListener(new SimpleSwipeListener() {
            @Override
            public void onSwipeOpened(SmartSwipeWrapper wrapper, SwipeConsumer consumer, int direction) {
                //direction: 
                //  1: left
                //  2: right
                //  4: top
                //  8: bottom
            }
        })
;

Antwoord 15

@Mirek Rusin answeir is erg goed.
Maar er is een kleine bug en er is een oplossing nodig –

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) {
                            if (getOnSwipeListener() != null) {
                                getOnSwipeListener().onSwipeRight();
                            }
                        } else {
                            if (getOnSwipeListener() != null) {
                                getOnSwipeListener().onSwipeLeft();
                            }
                        }
                        result = true;
                    }
                }
                else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffY > 0) {
                        if (getOnSwipeListener() != null) {
                            getOnSwipeListener().onSwipeBottom();
                        }
                    } else {
                        if (getOnSwipeListener() != null) {
                            getOnSwipeListener().onSwipeTop();
                        }
                    }
                    result = true;
                }

Wat is het verschil? We stellen resultaat = true in, alleen als we hebben gecontroleerd dat alle vereisten (zowel SWIPE_THRESHOLD als SWIPE_VELOCITY_THRESHOLD Ok zijn). Dit is belangrijk als we veegbewegingen weggooien als sommige vereisten niet worden bereikt, en we moeten iets doen in de onTouchEvent-methode van OnSwipeTouchListener!


Antwoord 16

Hier is een eenvoudige Android-code voor het detecteren van bewegingsrichting

In MainActivity.javaen activity_main.xmlschrijft u de volgende code:

MainActivity.java

import java.util.ArrayList;
import android.app.Activity;
import android.gesture.Gesture;
import android.gesture.GestureLibraries;
import android.gesture.GestureLibrary;
import android.gesture.GestureOverlayView;
import android.gesture.GestureOverlayView.OnGesturePerformedListener;
import android.gesture.GestureStroke;
import android.gesture.Prediction;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends Activity implements
        OnGesturePerformedListener {
    GestureOverlayView gesture;
    GestureLibrary lib;
    ArrayList<Prediction> prediction;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lib = GestureLibraries.fromRawResource(MainActivity.this,
                R.id.gestureOverlayView1);
        gesture = (GestureOverlayView) findViewById(R.id.gestureOverlayView1);
        gesture.addOnGesturePerformedListener(this);
    }
    @Override
    public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
        ArrayList<GestureStroke> strokeList = gesture.getStrokes();
        // prediction = lib.recognize(gesture);
        float f[] = strokeList.get(0).points;
        String str = "";
        if (f[0] < f[f.length - 2]) {
            str = "Right gesture";
        } else if (f[0] > f[f.length - 2]) {
            str = "Left gesture";
        } else {
            str = "no direction";
        }
        Toast.makeText(getApplicationContext(), str, Toast.LENGTH_LONG).show();
    }
}

activity_main.xml

<android.gesture.GestureOverlayView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android1="http://schemas.android.com/apk/res/android"
    xmlns:android2="http://schemas.android.com/apk/res/android"
    android:id="@+id/gestureOverlayView1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android1:orientation="vertical" >
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Draw gesture"
        android:textAppearance="?android:attr/textAppearanceMedium" />
</android.gesture.GestureOverlayView>

Antwoord 17

Als u enkele knoppen met acties wilt weergeven wanneer een lijstitem wordt geveegd, zijn er veel bibliotheken op internet die dit gedrag vertonen.
Ik heb de bibliotheek geïmplementeerd die ik op internet vond en ik ben zeer tevreden. Het is zeer eenvoudig te gebruiken en zeer snel. Ik heb de originele bibliotheek verbeterd en een nieuwe kliklistener toegevoegd voor het klikken op items. Ook heb ik een geweldige fontbibliotheek toegevoegd (http://fortawesome.github.io/Font-Awesome/) en nu kun je eenvoudig een nieuwe itemtitel toevoegen en de pictogramnaam van font awesome specificeren.

Hieris de github-link


Antwoord 18

public class TranslatorSwipeTouch implements OnTouchListener
{
   private String TAG="TranslatorSwipeTouch";
   @SuppressWarnings("deprecation")
   private GestureDetector detector=new GestureDetector(new TranslatorGestureListener());
   @Override
   public boolean onTouch(View view, MotionEvent event)
   {
     return detector.onTouchEvent(event);
   }
private class TranslatorGestureListener extends SimpleOnGestureListener 
{
    private final int GESTURE_THRESHOULD=100;
    private final int GESTURE_VELOCITY_THRESHOULD=100;
    @Override
    public boolean onDown(MotionEvent e) {
        return true;
    }
    @Override
    public boolean onFling(MotionEvent event1,MotionEvent event2,float velocityx,float velocityy)
    {
        try
        {
            float diffx=event2.getX()-event1.getX();
            float diffy=event2.getY()-event1.getY();
            if(Math.abs(diffx)>Math.abs(diffy))
            {
                if(Math.abs(diffx)>GESTURE_THRESHOULD && Math.abs(velocityx)>GESTURE_VELOCITY_THRESHOULD)
                {
                    if(diffx>0)
                    {
                        onSwipeRight();
                    }
                    else
                    {
                        onSwipeLeft();
                    }
                }
            }
            else
            {
                if(Math.abs(diffy)>GESTURE_THRESHOULD && Math.abs(velocityy)>GESTURE_VELOCITY_THRESHOULD)
                {
                    if(diffy>0)
                    {
                         onSwipeBottom();
                    }
                    else
                    {
                        onSwipeTop();
                    }
                }
            }
        }
        catch(Exception e)
        {
            Log.d(TAG, ""+e.getMessage());
        }
        return false;           
    }
    public void onSwipeRight()
    {
        //Toast.makeText(this.getClass().get, "swipe right", Toast.LENGTH_SHORT).show();
        Log.i(TAG, "Right");
    }
    public void onSwipeLeft()
    {
        Log.i(TAG, "Left");
        //Toast.makeText(MyActivity.this, "swipe left", Toast.LENGTH_SHORT).show();
    }
    public void onSwipeTop()
    {
        Log.i(TAG, "Top");
        //Toast.makeText(MyActivity.this, "swipe top", Toast.LENGTH_SHORT).show();
    }
    public void onSwipeBottom()
    {
        Log.i(TAG, "Bottom");
        //Toast.makeText(MyActivity.this, "swipe bottom", Toast.LENGTH_SHORT).show();
    }   
  }
 }

Antwoord 19

het gebruik van Edward Brey’s antwoordin Kotlin

view.setOnTouchListener(object: OnSwipeTouchListener(this) {
      override fun onSwipeLeft() {
        super.onSwipeLeft()
      }
      override fun onSwipeRight() {
        super.onSwipeRight()
      }
    }
 )

Antwoord 20

Ik weet dat het een beetje laat is sinds 2012, maar ik hoop dat het iemand zal helpen, aangezien ik denk dat het een kortere en schonere code is dan de meeste antwoorden:

view.setOnTouchListener((v, event) -> {
int action = MotionEventCompat.getActionMasked(event);
switch(action) {
    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);
}
    });

natuurlijk kunt u alleen de relevante gebaren aan u overlaten.

src: https://developer.android.com/training/gestures/detector

Other episodes