Mobility

Use Android's gesture detector to translate a swipe into an event

When developing an Android app, you can use the intuitive Gesture Detector class horizontally, vertically, and diagonally to translate subtle motions into distinct events.

One of the coolest things about the modern smartphone is the wide array of input and sensory devices available. In the past, we've covered Android's internal vibrator and the accelerometer. This tutorial is about Android's impressive Gesture Detector class, which you can use to translate subtle motions into distinct events for navigating a complex application on a small form factor display.

You can follow along with the step-by-step tutorial or download the entire project. All the gestures handled in this tutorial are one-touch gestures because I built the project to support the widest range of Android devices; multi-touch gestures weren't fully supported until Android 2.2. If the response to this tutorial warrants it, we can cover multi-touch gestures in a future post.

1. Create a new Android project. Target Android 1.6 or higher. Be sure to rename the startup activity to Main.java.

2. In the /res file I created a new folder called /Drawable and included my drawables (Figure A and Figure B). Figure A

Figure B

3. With our images in place, we can move on to the layout. In /res, I modified the main.xml layout to include another linear layout and the placeholder for our runtime images.

main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Swipe Demo"
        android:gravity="center"
        android:layout_margin="10dip" />
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical"
            android:gravity="center">
                 <ImageView
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_gravity="center"
                     android:gravity="center"
                     android:layout_margin="10dip"
                     android:id="@+id/image_place_holder"/>
           </LinearLayout>
</LinearLayout>

4. Moving on to the /src folder, we will want to let Main.java extend Activity and implement OnGestureListener. We will create a class variable for our gesture detector and instantiate it in the on create.

Main.java
package com.authorwjf.gesture;
import android.app.Activity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.widget.ImageView;
public class Main extends Activity implements OnGestureListener {
        private GestureDetector gDetector;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        gDetector = new GestureDetector(this);
    }
}

5. The on gesture detector listener requires that we override six methods, though for the demo we will only care what happens during the on fling. We do a quick check to determine if the motion occurred from top to bottom or bottom to top and display the appropriate facing chevrons.

@Override
public boolean onDown(MotionEvent arg0) {
        // TODO Auto-generated method stub
        return false;
}
@Override
public boolean onFling(MotionEvent start, MotionEvent finish, float xVelocity, float yVelocity) {
        if (start.getRawY() < finish.getRawY()) {
                    ((ImageView)findViewById(R.id.image_place_holder)).setImageResource(R.drawable.down);
        } else {
                    ((ImageView)findViewById(R.id.image_place_holder)).setImageResource(R.drawable.up);
        }
        return true;
}
@Override
public void onLongPress(MotionEvent arg0) {
        // TODO Auto-generated method stub
}
@Override
public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2, float arg3) {
          // TODO Auto-generated method stub
          return false;
}
@Override
public void onShowPress(MotionEvent arg0) {
        // TODO Auto-generated method stub
}
@Override
public boolean onSingleTapUp(MotionEvent arg0) {
        // TODO Auto-generated method stub
        return false;
}

6. An important and often overlooked step in correctly wiring the gesture detector is overriding the activity's on touch handler and feeding the result to the gesture detector; this is how all gesture detections occur, as the result of re-routing an on touch. Without this step, your gesture detector will never fire.

@Override
public boolean onTouchEvent(MotionEvent me) {
return gDetector.onTouchEvent(me);
}
While you can run the application on the emulator, I don't recommend it. Gesture detection with the mouse is at best clunky; instead, fire up the app on your phone via ADB and have a look (Figure C). Figure C

The direction of the chevrons indicate the direction of your last swipe. While we don't currently consider the velocity calculation, which is part of the motion event, it should be obvious how this value could be used in conjunction with the UI to produce various effects based on how hard the user flicks his or her finger.

The gesture detector can be used horizontally, vertically, and diagonally for controlling everything from turning pages in a document to spinning the wheels on a slot machine. Best of all, it's intuitive and natural feeling and usually requires little to no screen real estate.

About

William J Francis began programming computers at age eleven. Specializing in embedded and mobile platforms, he has more than 20 years of professional software engineering under his belt, including a four year stint in the US Army's Military Intellige...

1 comments
Abilasco
Abilasco

Great Tutorial! Is there a NEXT STEP TO THIS AMAZING TUT?

Editor's Picks