Android.view.GestureDetector
lastmod 2018-08-17created 2016-11-241 edits
An explanation of gestures in Android.
How to handle swipe gestures
- http://stackoverflow.com/questions/4139288/android-how-to-handle-right-to-left-swipe-gestures
- http://stackoverflow.com/questions/937313/android-basic-gesture-detection
- http://pulsebeat.tistory.com/27
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.GestureDetector.OnGestureListener;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
public class GestureActivity extends Activity implements OnGestureListener {
private LinearLayout main;
private TextView viewA;
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;
private GestureDetector gestureScanner;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gestureScanner = new GestureDetector(this);
main = new LinearLayout(this);
main.setBackgroundColor(Color.GRAY);
main.setLayoutParams(new LinearLayout.LayoutParams(320, 480));
viewA = new TextView(this);
viewA.setBackgroundColor(Color.WHITE);
viewA.setTextColor(Color.BLACK);
viewA.setTextSize(30);
viewA.setGravity(Gravity.CENTER);
viewA.setLayoutParams(new LinearLayout.LayoutParams(320, 80));
main.addView(viewA);
setContentView(main);
}
@Override
public boolean onTouchEvent(MotionEvent me) {
return gestureScanner.onTouchEvent(me);
}
public boolean onDown(MotionEvent e) {
viewA.setText("-" + "DOWN" + "-");
return true;
}
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) {
Toast.makeText(getApplicationContext(), "Left Swipe", Toast.LENGTH_SHORT).show();
}
// left to right swipe
else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
Toast.makeText(getApplicationContext(), "Right Swipe", Toast.LENGTH_SHORT).show();
}
// down to up swipe
else if (e1.getY() - e2.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) {
Toast.makeText(getApplicationContext(), "Swipe up", Toast.LENGTH_SHORT).show();
}
// up to down swipe
else if (e2.getY() - e1.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) {
Toast.makeText(getApplicationContext(), "Swipe down", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
}
return true;
}
public void onLongPress(MotionEvent e) {
Toast mToast = Toast.makeText(getApplicationContext(), "Long Press", Toast.LENGTH_SHORT);
mToast.show();
}
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
viewA.setText("-" + "SCROLL" + "-");
return true;
}
public void onShowPress(MotionEvent e) {
viewA.setText("-" + "SHOW PRESS" + "-");
}
public boolean onSingleTapUp(MotionEvent e) {
Toast mToast = Toast.makeText(getApplicationContext(), "Single Tap", Toast.LENGTH_SHORT);
mToast.show();
return true;
}
}
I used the term Swipe (to swing, a strong blow), and left it as is because I wasn't sure how to render it in Korean. The simplest way to picture it is flipping through a home screen made up of several pages with your finger.
The core of the code is GestureDetector. If the activity inherits OnGestureListener, it can use GestureDetector. Create the GestureDetector while registering it with the activity. Then, through onTouchEvent, hook it up to the onTouchEvent of the GestureDetector object. This completes the basic setup. After that, you can inherit and use whichever features you want. Above, you can see that onDown, onLongPress, onScroll, onShowPress, onSingleTapUp, and onFling are inherited and implemented. As the function names suggest, each one is called depending on which touch action is in progress. I think you can understand the others intuitively, but onFling, which looks complex, needs a bit of thought. Let's first look at the three variables below. Once you understand these, you'll see that the structure is very simple.
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;
Touch events come in through the onFling event. Looking at the arguments passed to onFling, there are two motion events and float velocities. You probably already get the idea. The first argument is the event at the moment the touch starts, and the second argument is the event at the moment the touch is released. The third argument is the velocity along the X axis, and the fourth is the argument along the Y axis. In other words, with these four events you can tell which direction the Swipe action goes.
Telling apart Swipe actions in the four directions is done by measuring distance and velocity. The SWIPE_MIN_DISTANSE argument is the smallest distance recognized as a Swipe. The distance must be at least the set value to be recognized as a Swipe action. SWIPE_MAX_OFF_PATH can be thought of as the maximum recognized distance. It means Scrolling beyond that distance is excluded. The last one, SWIPE_THRESHOLD_VELOCITY, is the velocity. The touch action must be made at or above a given velocity in each direction to be recognized as a Swipe.
Now if you look at the code above, its structure will be clear at a glance. It compares the start and end coordinates to compare distances, and if the distance and velocity are at an adequate level, it recognizes a Swipe and shows a toast. Using this approach, put in whatever action you want, such as switching screens.
Default value for recognizing the Drag range
When you need the minimum mouse travel distance for a SWIPE, use the predefined default value.