Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect swipe direction between left/right and up/down

My Question: How do I detect when a user moves their finger up/down vs left/right (and how do I know which direction of those groups their finger moved)?

My Situation: I want to change the brightness of my app when they move their finger up and down (up = brighter, down = darker), and I want to switch between activities and/or views based on their left/right swipe.

like image 965
kentcdodds Avatar asked Oct 26 '12 22:10

kentcdodds


People also ask

How do I change left and right swipe on Android?

Tap General settings. Find Mail swipe actions and tap it. Tap Change next to either Right swipe or Left swipe. From there, you can adjust what that directional swipe does.


2 Answers

I wrote a simple class for this: it's well documented so I wont explain it here

public class OnSwipeListener extends GestureDetector.SimpleOnGestureListener {      @Override     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {          // Grab two events located on the plane at e1=(x1, y1) and e2=(x2, y2)         // Let e1 be the initial event         // e2 can be located at 4 different positions, consider the following diagram         // (Assume that lines are separated by 90 degrees.)         //         //         //         \ A  /         //          \  /         //       D   e1   B         //          /  \         //         / C  \         //         // So if (x2,y2) falls in region:         //  A => it's an UP swipe         //  B => it's a RIGHT swipe         //  C => it's a DOWN swipe         //  D => it's a LEFT swipe         //          float x1 = e1.getX();         float y1 = e1.getY();          float x2 = e2.getX();         float y2 = e2.getY();          Direction direction = getDirection(x1,y1,x2,y2);         return onSwipe(direction);     }      /** Override this method. The Direction enum will tell you how the user swiped. */     public boolean onSwipe(Direction direction){         return false;     }      /**      * Given two points in the plane p1=(x1, x2) and p2=(y1, y1), this method      * returns the direction that an arrow pointing from p1 to p2 would have.      * @param x1 the x position of the first point      * @param y1 the y position of the first point      * @param x2 the x position of the second point      * @param y2 the y position of the second point      * @return the direction      */     public Direction getDirection(float x1, float y1, float x2, float y2){         double angle = getAngle(x1, y1, x2, y2);         return Direction.fromAngle(angle);     }      /**      *      * Finds the angle between two points in the plane (x1,y1) and (x2, y2)      * The angle is measured with 0/360 being the X-axis to the right, angles      * increase counter clockwise.      *      * @param x1 the x position of the first point      * @param y1 the y position of the first point      * @param x2 the x position of the second point      * @param y2 the y position of the second point      * @return the angle between two points      */     public double getAngle(float x1, float y1, float x2, float y2) {          double rad = Math.atan2(y1-y2,x2-x1) + Math.PI;         return (rad*180/Math.PI + 180)%360;     }       public enum Direction{         up,         down,         left,         right;          /**          * Returns a direction given an angle.          * Directions are defined as follows:          *          * Up: [45, 135]          * Right: [0,45] and [315, 360]          * Down: [225, 315]          * Left: [135, 225]          *          * @param angle an angle from 0 to 360 - e          * @return the direction of an angle          */         public static Direction fromAngle(double angle){             if(inRange(angle, 45, 135)){                 return Direction.up;             }             else if(inRange(angle, 0,45) || inRange(angle, 315, 360)){                 return Direction.right;             }             else if(inRange(angle, 225, 315)){                 return Direction.down;             }             else{                return Direction.left;            }          }         /**          * @param angle an angle          * @param init the initial bound          * @param end the final bound          * @return returns true if the given angle is in the interval [init, end).          */         private static boolean inRange(double angle, float init, float end){             return (angle >= init) && (angle < end);         }     }  } 

To use simply extend the OnSwipeListener and override the onSwipe method

like image 71
fernandohur Avatar answered Sep 24 '22 06:09

fernandohur


You simply have to extend SimpleOnGestureListener class,

Declare this in your class,

private static final int SWIPE_MIN_DISTANCE = 120; private static final int SWIPE_MAX_OFF_PATH = 250; private static final int SWIPE_THRESHOLD_VELOCITY = 200; 

As an example for horizontal swipe you can see the below code,

 class MyGestureDetector extends SimpleOnGestureListener {     @Override     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,             float velocityY) {         try {             if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH){                 return false;             }             // right to left swipe             if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE                     && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {                 onLeftSwipe();             }              // left to right swipe             else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE                     && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {                 onRightSwipe();             }         } catch (Exception e) {          }         return false;       }    } 

You can do this similarly for vertical swipe purpose.

like image 27
Ice Box Avatar answered Sep 22 '22 06:09

Ice Box