如何检测滑动左或右在 Android?

我在机器人中有一个 EditText视图。在这一点上,我想检测滑动左或右。我能够得到它在一个空白的空间使用下面的代码。但是,当我在 EditText上滑动时,这不工作。我该怎么做?如果我做错了什么,请告诉我。谢谢你。

代码使用:

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;
}
}
178917 次浏览

Simplest left to right swipe detector:

In your activity class add following attributes:

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

and override onTouchEvent() method:

@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);
}

I like the code from @user2999943. But just some minor changes for my own purposes.

@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);
}

This is a cute class I use (in cases I want to catch event on a View, if it is a ViewGroup, I use the second implementation):

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
}


}

and this is a use example:

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 some cases you would like to detect the swipe gestures on a container and pass down the touch Events to the childs so in that case you can create a Custom View group, lets say RelativeLayout and override onInterceptTouchEvent , and there you can detect the swipe event without blocking the pass of Touch Event to your child views,for Example:

    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;
}
}
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;
}

I wrote a simple class that makes it easy to detect the swipe events - TOP, RIGHT, BOTTOM, LEFT.

1: Detect single swipe event

// 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: Detect any of the swipe events with one callback.

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
}
});

Here is a blog post with the explanation on how to use: http://bmutinda.com/android-detect-swipe-events/

I have also created a Gist for the code snippets available here: https://gist.github.com/bmutinda/9578f70f1df9bd0687b8

Thanks.

Left to Right and Right to Left Swipe Detector

Firstly, declare two variable of float datatype.

private float x1, x2;

Secondly, wireup your xml view in java. Like I have ImageView

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

Thirdly, setOnTouchListener on your 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;
}
});

Swipe events are a kind of onTouch events. Simply simplifying @Gal Rom 's answer, just keep track of the vertical an horizontal deltas, and with a little math you can determine what kind of swipe a touchEvent was. (Again, let me stress that this was OBSENELY based to a previous answer, but the simplicity may appeal to novices). The idea is to extend an OnTouchListener, detect what kind of swipe (touch) just happened and call specific methods for each kind.

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();
}
}

I want to add on to the accepted answer which works partially, but is missing the time variable, that makes it perfect.

Simplest left to right swipe detector with a time variable:

In your activity class add following attributes:

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

and override onTouchEvent () method:

    @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);
}

the best answer is @Gal Rom 's. there is more information about it: touch event return's to child views first. and if you define onClick or onTouch listener for them, parnt view (for example fragment) will not receive any touch listener. So if you want define swipe listener for fragment in this situation, you must implement it in a new class:

    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;
}
}

I changed @Gal Rom 's class. So it can detect both right and left swipe and specially it returns onInterceptTouchEvent true after detect. its important because if we dont do it some times child views maybe receive event and both of Swipe for fragment and onClick for child view (for example) runs and cause some issues. after making this class, you must change your fragment xml file:

    <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>

you see that begin tag is the class that we made. now in fragment class:

            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();
}

It's a little complicated but works perfect :)

Detect swipe in four direction

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

and

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;
}

I think what you want is called a fling. The MotionEvents can be used to determine the direction of the fling.

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

If you want to catch the event from the starting of the swipe you can use MotionEvent.ACTION_MOVE and store the first value to compare

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;


}
});

this should help you maybe...

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);
}
};

After a full day working on this feature finally able to get the right answer.

First, create the following classes:

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;
}
}

Finally on the object that you want to apply. My example:

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

Good luck .

Short and easy version:

1. First create this abstract class

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.Then create a concrete class implementing what you need:

public class SwipeListener extends HorizontalSwipeListener {


public SwipeListener() {
super(200);
}


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


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


}

You should be extend a class from View.OnTouchListener and handle the onTouch method by overriding it.

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()
}
}

You can just easily implement it like this in your Activity or 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()
}
}

here is generic swipe left detector for any view in kotlin using databinding

@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
}
})
}

and then to use it in your layout:

app:onSwipeLeft="@{() -> viewModel.swipeLeftHandler()}"