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