Android: touchscreen ‘swipe’ movement detection
Posted by Dimitri | Jan 11th, 2011 | Filed under Programming
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!
Excelent info.
Thanks!!
One of the best tutorials!
Thanks!
bookmarked as one the best, clear cons… i forget how to spell the last word
Good job. This is EXACTLY what i needed!
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.
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:
Try:
Reallyinteresting. I ENJOY it !!!!!!! THANKS
How do i bind this View to something? I mean, how do i implement this?
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.
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.