How to detect the swipe left or Right in Android?
Solution 1:
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);
}
Solution 2:
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);
}
Solution 3:
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;
}
}
Solution 4:
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();
}
}
Solution 5:
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.