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:

private float initialX = 0;
private float initialY = 0;
private float deltaX = 0;
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:

@Override
public boolean onTouchEvent(MotionEvent event)
{
	//This prevents touchscreen events from flooding the main thread
	synchronized (event)
	{
		try
		{
			//Waits 16ms.
			event.wait(16);

			//The 'swipe' code goes here

			return true;
		}
		catch (InterruptedException e)
		{
			return true;
		}
	}

}

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:

public class YourView extends View
{
	private float initialX = 0;
	private float initialY = 0;
	private float deltaX = 0;
	private float deltaY = 0;

	@Override
	public boolean onTouchEvent(MotionEvent event)
	{
		//This prevents touchscreen events from flooding the main thread
		synchronized (event)
		{
			try
			{
				//Waits 16ms.
				event.wait(16);

				//when user touches the screen
				if(event.getAction() == MotionEvent.ACTION_DOWN)
				{
					//reset deltaX and deltaY
					deltaX = deltaY = 0;

					//get initial positions
					initialX = event.getRawX();
					initialY = event.getRawY();
				}

				//when screen is released
				if(event.getAction() == MotionEvent.ACTION_UP)
				{
					deltaX = event.getRawX() - initialX;
					deltaY = event.getRawY() - initialY;

					//swipped up
					if(deltaY < 0)
					{
						//make your object/character move right
					}
					else
					{
						//make your object/character move left
					}

					return true;
				}
			}

			catch (InterruptedException e)
			{
				return true;
			}
		}
	}
}

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:

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

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.

    {
    	private float initialX = 0;  
        private float initialY = 0;  
        private float deltaX = 0;  
        private float deltaY = 0;  
      
        @Override  
        public boolean onTouchEvent(MotionEvent event)  
        {  
            //This prevents touchscreen events from flooding the main thread  
            synchronized (event)  
            {  
                try  
                {  
                    //Waits 16ms.  
                    event.wait(16);  
      
                    //when user touches the screen  
                    if(event.getAction() == MotionEvent.ACTION_DOWN)  
                    {  
                        //reset deltaX and deltaY  
                        deltaX = 0;
                        deltaY = 0;  
      
                        //get initial positions  
                        initialX = event.getRawX();  
                        initialY = event.getRawY();  
                    }  
      
                    //when screen is released  
                    if(event.getAction() == MotionEvent.ACTION_UP)  
                    {  
                        deltaX = event.getRawX() - initialX;  
                        deltaY = event.getRawY() - initialY;  
      
                        //swipped up  
                        if(deltaY < 0) //swipped down  
                        {  
                            //make your object/character move down
                        	if (mDirection != NORTH)
                        	{
                                mNextDirection = SOUTH;
                            }
                            return (true);
                        }  
                        
      
                        //swipped right  
                        if(deltaX >0)  
                        {  
                            //make your object/character move right
                        	if (mDirection != WEST) 
                        	{
                                mNextDirection = EAST;
                            }
                            return (true);
                        }  
                        //swiped left
                        if(deltaX<0)  
                        {  
                            //make your object/character move left
                        	if (mDirection != EAST)
                        	{
                                mNextDirection = WEST;
                            }
                            return (true);
                        }  
                        return true;
                    }  
                }  
       
                catch (InterruptedException e)  
                {  
                    return true;  
                }  
            }
    		return true; 
        }
    
    • 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:

      if(event.getAction() == MotionEvent.ACTION_UP)  
      {  
          deltaX = event.getRawX() - initialX;  
          deltaY = event.getRawY() - initialY;    
        
          if(deltaY < 0) 
          {  
              //arbitrary code
              return (true);
          } 
          if(deltaY > 0) 
          {  
              //arbitrary code
              return (true);
          } 
      
          if(deltaX > 0) 
          {  
              //arbitrary code
              return (true);
          } 
      
          if(deltaX < 0) 
          {  
              //arbitrary code
              return (true);
          } 
      }
      

      Try:

      if(event.getAction() == MotionEvent.ACTION_UP)  
      {  
          deltaX = event.getRawX() - initialX;  
          deltaY = event.getRawY() - initialY;    
        
          if(deltaY < 0) 
          {  
              //arbitrary code
          } 
          else 
          {  
              //arbitrary code
          } 
      
          if(deltaX < 0) 
          {  
              //arbitrary code
          }
          else
          {  
              //arbitrary code
          } 
      
          //Just a single return statement
          return (true);
      }
      
  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