Get the FULL version

Android: touchscreen ‘swipe’ movement detection

Android: touchscreen ‘swipe’ movement detection thumbnail

This post explains how to code a simple swipe screen movement detection that can be used to control characters and other objects on an Android game or any other application.

All this code is written inside the View class, so open it up and let’s get to it. The first thing we will have to do is to create four different variables: one pair will store where the screen was touched, and the other one will be used to store the difference between the location where the screen has been pressed and where the screen has been released. Create this variables and assign zero to all of then, like this:

  1. private float initialX = 0;  
  2. private float initialY = 0;  
  3. private float deltaX = 0;  
  4. private float deltaY = 0;  

With that set of variables created, let’s get to the method that will handle the touchscreen events. This method is already part of the View class, it’s the onTouchEvent() method, so it just needs to be overridden and then, we will add the code to it. When handling touchscreen events on Android, one must know that these will eventually flood the application, causing a performance loss (more information on that here and here).

To solve this problem, call the wait() method inside the onTouchEvent(), but this isn’t as simple as it looks, because first, it is necessary to get the thread’s handle with Java’s synchronized keyword. We will use the MotionEvent object for that. Finally, we will call the wait() method and surround it with a try/catch block, to avoid an exception being thrown. As recommended by Chris Pruett we will make the thread wait 16 ms. Here’s the code for all that:

  1. @Override  
  2. public boolean onTouchEvent(MotionEvent event)  
  3. {  
  4.     //This prevents touchscreen events from flooding the main thread  
  5.     synchronized (event)  
  6.     {  
  7.         try  
  8.         {  
  9.             //Waits 16ms.  
  10.             event.wait(16);  
  11.   
  12.             //The 'swipe' code goes here  
  13.   
  14.             return true;  
  15.         }  
  16.         catch (InterruptedException e)  
  17.         {  
  18.             return true;  
  19.         }  
  20.     }  
  21.   
  22. }  

After all this trouble, let’s explain how the ‘swipe’ code detection works. It starts by storing the location of the touch event on the screen at the initialX and initialY variables. Then, after the screen is released, the difference between the initial and final touch coordinates is calculated and stored in deltaX and deltaY variables.

With these last two variables, all we need to do is to check if they are positive or negative. If deltaX is positive, the screen had been touched from left to right, if negative, it was touched from right to left. The same applies to deltaY: positive values means that the movement started from the top and ended on the bottom and negative values indicate that movement was executed from the bottom to the top.

Adding the ‘swipe’ detection part of the code and adding the above pieces, the code will be like this:

  1. public class YourView extends View  
  2. {  
  3.     private float initialX = 0;  
  4.     private float initialY = 0;  
  5.     private float deltaX = 0;  
  6.     private float deltaY = 0;  
  7.   
  8.     @Override  
  9.     public boolean onTouchEvent(MotionEvent event)  
  10.     {  
  11.         //This prevents touchscreen events from flooding the main thread  
  12.         synchronized (event)  
  13.         {  
  14.             try  
  15.             {  
  16.                 //Waits 16ms.  
  17.                 event.wait(16);  
  18.   
  19.                 //when user touches the screen  
  20.                 if(event.getAction() == MotionEvent.ACTION_DOWN)  
  21.                 {  
  22.                     //reset deltaX and deltaY  
  23.                     deltaX = deltaY = 0;  
  24.   
  25.                     //get initial positions  
  26.                     initialX = event.getRawX();  
  27.                     initialY = event.getRawY();  
  28.                 }  
  29.   
  30.                 //when screen is released  
  31.                 if(event.getAction() == MotionEvent.ACTION_UP)  
  32.                 {  
  33.                     deltaX = event.getRawX() - initialX;  
  34.                     deltaY = event.getRawY() - initialY;  
  35.   
  36.                     //swipped up  
  37.                     if(deltaY < 0)  
  38.                     {  
  39.                         //make your object/character move right  
  40.                     }  
  41.                     else  
  42.                     {  
  43.                         //make your object/character move left  
  44.                     }  
  45.   
  46.                     return true;  
  47.                 }  
  48.             }  
  49.   
  50.             catch (InterruptedException e)  
  51.             {  
  52.                 return true;  
  53.             }  
  54.         }  
  55.     }  
  56. }  

To make the movement more precise, the X or the Y axis must be set as a preferred direction. To set the Y axis as the preferred direction, just check if the absolute deltaY value is greater than the deltaX value. To set the X axis as the preferred direction, just make the opposite, check if the absolute deltaX value is greater than the deltaY value, like this:

  1. //only makes up swipe detection valid if the vertical swipe was greater than the horizontal one.  
  2. if(deltaY=Math.abs(deltaX))  
  3. {  
  4.      //Code to move character/object up  
  5. }  

Don’t forget to comment!

11 Comments to “Android: touchscreen ‘swipe’ movement detection”

  1. Mers says:

    Excelent info.
    Thanks!!

  2. Kal says:

    One of the best tutorials!

  3. Vik says:

    bookmarked as one the best, clear cons… i forget how to spell the last word

  4. JS says:

    Good job. This is EXACTLY what i needed!

  5. Mh says:

    This was very helpful. I have a problem though it only works for Up and down, not left and right. I dont know what is causing the problem and i dont know how to fix it Please help.

    1. {  
    2.     private float initialX = 0;    
    3.     private float initialY = 0;    
    4.     private float deltaX = 0;    
    5.     private float deltaY = 0;    
    6.     
    7.     @Override    
    8.     public boolean onTouchEvent(MotionEvent event)    
    9.     {    
    10.         //This prevents touchscreen events from flooding the main thread    
    11.         synchronized (event)    
    12.         {    
    13.             try    
    14.             {    
    15.                 //Waits 16ms.    
    16.                 event.wait(16);    
    17.     
    18.                 //when user touches the screen    
    19.                 if(event.getAction() == MotionEvent.ACTION_DOWN)    
    20.                 {    
    21.                     //reset deltaX and deltaY    
    22.                     deltaX = 0;  
    23.                     deltaY = 0;    
    24.     
    25.                     //get initial positions    
    26.                     initialX = event.getRawX();    
    27.                     initialY = event.getRawY();    
    28.                 }    
    29.     
    30.                 //when screen is released    
    31.                 if(event.getAction() == MotionEvent.ACTION_UP)    
    32.                 {    
    33.                     deltaX = event.getRawX() - initialX;    
    34.                     deltaY = event.getRawY() - initialY;    
    35.     
    36.                     //swipped up    
    37.                     if(deltaY < 0//swipped down    
    38.                     {    
    39.                         //make your object/character move down  
    40.                         if (mDirection != NORTH)  
    41.                         {  
    42.                             mNextDirection = SOUTH;  
    43.                         }  
    44.                         return (true);  
    45.                     }    
    46.                       
    47.     
    48.                     //swipped right    
    49.                     if(deltaX >0)    
    50.                     {    
    51.                         //make your object/character move right  
    52.                         if (mDirection != WEST)   
    53.                         {  
    54.                             mNextDirection = EAST;  
    55.                         }  
    56.                         return (true);  
    57.                     }    
    58.                     //swiped left  
    59.                     if(deltaX<0)    
    60.                     {    
    61.                         //make your object/character move left  
    62.                         if (mDirection != EAST)  
    63.                         {  
    64.                             mNextDirection = WEST;  
    65.                         }  
    66.                         return (true);  
    67.                     }    
    68.                     return true;  
    69.                 }    
    70.             }    
    71.      
    72.             catch (InterruptedException e)    
    73.             {    
    74.                 return true;    
    75.             }    
    76.         }  
    77.         return true;   
    78.     }  
    • DimasTheDriver says:

      I guess the problem is that you are returning true inside each if statement, so the code execution at the onTouchEvent() function is exiting early. Also, if possible, try to use a if-else instead of two ifs, for each direction. For instance, in a horizontal direction, you can’t be swiping left and right at the same time.

      You should place only a single return (true); after all if statements.

      Instead of:

      1. if(event.getAction() == MotionEvent.ACTION_UP)    
      2. {    
      3.     deltaX = event.getRawX() - initialX;    
      4.     deltaY = event.getRawY() - initialY;      
      5.     
      6.     if(deltaY < 0)   
      7.     {    
      8.         //arbitrary code  
      9.         return (true);  
      10.     }   
      11.     if(deltaY > 0)   
      12.     {    
      13.         //arbitrary code  
      14.         return (true);  
      15.     }   
      16.   
      17.     if(deltaX > 0)   
      18.     {    
      19.         //arbitrary code  
      20.         return (true);  
      21.     }   
      22.   
      23.     if(deltaX < 0)   
      24.     {    
      25.         //arbitrary code  
      26.         return (true);  
      27.     }   
      28. }  

      Try:

      1. if(event.getAction() == MotionEvent.ACTION_UP)    
      2. {    
      3.     deltaX = event.getRawX() - initialX;    
      4.     deltaY = event.getRawY() - initialY;      
      5.     
      6.     if(deltaY < 0)   
      7.     {    
      8.         //arbitrary code  
      9.     }   
      10.     else   
      11.     {    
      12.         //arbitrary code  
      13.     }   
      14.   
      15.     if(deltaX < 0)   
      16.     {    
      17.         //arbitrary code  
      18.     }  
      19.     else  
      20.     {    
      21.         //arbitrary code  
      22.     }   
      23.   
      24.     //Just a single return statement  
      25.     return (true);  
      26. }  
  6. ANGELO says:

    Reallyinteresting. I ENJOY it !!!!!!! THANKS

  7. Guilherme says:

    How do i bind this View to something? I mean, how do i implement this?

    • DimasTheDriver says:

      To use the code on this post, just override the onTouchEvent() method inside your own View. You don’t have/need to bind the View above. It’s just an example.

  8. sruthi says:

    Hi,

    I need swiping function code in Android where the page containg dynamic buttons should present.Swiping should be in both directions like left t right and right to left.

Leave a Comment

Post Comments RSS