| page.title=Gestures |
| @jd:body |
| |
| <p>Touch screens are a great way to interact with applications on |
| mobile devices. With a touch screen, users can easily tap, drag, fling, |
| or slide to quickly perform actions in their favorite applications. |
| For app developers. the Android framework makes it's easy to |
| recognize simple actions, like a swipe, but it has been more |
| difficult to handle complicated gestures, sometimes requiring |
| developers to write a lot of code.</p> |
| |
| <p>That's why we introduced a new gestures API in Android 1.6. This API, located |
| in the new package {@link android.gesture}, lets you store, load, draw, and |
| recognize gestures. This article will show you how you can use the |
| <code>android.gesture</code> API in your applications. Before going any further, |
| you should <a |
| href="http://code.google.com/p/apps-for-android/downloads/detail?name= |
| GesturesDemos.zip&can=2&q=#makechanges">download the source code |
| of the examples</a>.</p> |
| |
| <h3>Creating a gestures library</h3> |
| |
| <p>Android 1.6 and higher SDK platforms include a new application pre-installed |
| on the emulator, called Gestures Builder. You can use this application to create |
| a set of pre-defined gestures for your own application. It also serves as an |
| example of how to let the user define his own gestures in your applications. You |
| can find the source code of Gestures Builders in the samples directory of each |
| SDK platform. In our example we will use Gestures Builder to generate a set of |
| gestures for us (make sure to create an AVD with an SD card image to use |
| Gestures Builder.) The screenshot below shows what the application looks like |
| after adding a few gestures:</p> |
| |
| <img src="images/gestures_006.png" style="width: 320px; height: 480px;"> |
| |
| <p>As you can see, a gesture is always associated with a name. That name is very |
| important because it identifies each gesture within your application. The names |
| do not have to be unique. Actually it can be very useful to have several |
| gestures with the same name to increase the precision of the recognition. Every |
| time you add or edit a gesture in the Gestures Builder, a file is generated on |
| the emulator's SD card, <code>/sdcard/gestures</code>. This file contains the |
| description of all the gestures, and you will need to package it inside your |
| application inside the resources directory, in |
| <code>/res/raw</code>.</p> |
| |
| <h3>Loading the gestures library</h3> |
| |
| <p>Now that you have a set of pre-defined gestures, you must load it inside your |
| application. This can be achieved in several ways but the easiest is to use the |
| <code>GestureLibraries</code> class:</p> |
| |
| <pre class="prettyprint">mLibrary = GestureLibraries.fromRawResource(this, R.raw.spells); |
| if (!mLibrary.load()) { |
| finish(); |
| }</pre> |
| |
| <p>In this example, the gesture library is loaded from the file |
| <code>/res/raw/spells</code>. You can easily load libraries from other sources, |
| like the SD card, which is very important if you want your application to be |
| able to save the library; a library loaded from a raw resource is read-only and |
| cannot be modified. The following diagram shows the structure of a library:</p> |
| |
| <img src="images/gestures_002.png" style="width: 600px; height: 512px;"> |
| |
| <h3>Recognizing gestures</h3> |
| |
| <p>To start recognizing gestures in your application, all you have to do |
| is add a <code>GestureOverlayView</code> to your XML layout:</p> |
| |
| <pre><android.gesture.GestureOverlayView |
| android:id="@+id/gestures" |
| android:layout_width="fill_parent" |
| android:layout_height="0dip" |
| android:layout_weight="1.0" /></pre> |
| |
| <p>Notice that the <code>GestureOverlayView</code> |
| is not part of the usual android.widget package. Therefore, you must |
| use its fully qualified name. A gesture overlay acts as a simple |
| drawing board on which the user can draw his gestures. You can tweak |
| several visual properties, like the color and the width of the stroke |
| used to draw gestures, and register various listeners to follow what |
| the user is doing. The most commonly used listener is |
| <code>GestureOverlayView.OnGesturePerformedListener</code>, |
| which fires whenever a user is done drawing a gesture:</p> |
| |
| <pre>GestureOverlayView gestures = (GestureOverlayView) findViewById(R.id.gestures); |
| gestures.addOnGesturePerformedListener(this);</pre> |
| |
| <p>When the listener fires, you can ask the <code>GestureLibrary</code> |
| to try to recognize the gesture. In return, you will get a list of |
| Prediction instances, each with a name - the same name you entered in |
| the Gestures Builder - and a score. The list is sorted by descending |
| scores; the higher the score, the more likely the associated gesture is |
| the one the user intended to draw. The following code snippet |
| demonstrates how to retrieve the name of the first prediction:</p> |
| |
| <pre>public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { |
| ArrayList<prediction> predictions = mLibrary.recognize(gesture); |
| |
| // We want at least one prediction |
| if (predictions.size() > 0) { |
| Prediction prediction = predictions.get(0); |
| // We want at least some confidence in the result |
| if (prediction.score > 1.0) { |
| // Show the spell |
| Toast.makeText(this, prediction.name, Toast.LENGTH_SHORT).show(); |
| } |
| } |
| }</pre> |
| |
| <p>In this example, the first prediction is taken into account only if it's |
| score is greater than 1.0. The threshold you use is entirely up to you |
| but know that scores lower than 1.0 are typically poor matches. And |
| this is all the code you need to create a simple application that can |
| recognize pre-defined gestures (see the source code of the project |
| GesturesDemo):</p> |
| |
| <img src="images/gestures.png" style="width: 320px; height: 480px;"> |
| |
| <h3>Gestures overlay</h3> |
| |
| <p>In the example above, the <code>GestureOverlayView</code> was used |
| as a normal view, embedded inside a <code>LinearLayout</code>. |
| However, as its name suggests, it can also be used as an overlay on top |
| of other views. This can be useful to recognize gestures in a game or |
| just anywhere in the UI of an application. In the second example, |
| called GesturesListDemo, we'll create an overlay on top of a list of |
| contacts. We start again in Gestures Builder to create a new set of |
| pre-defined gestures:</p> |
| |
| <p><img src="images/gestures_005.png" style="width: 320px; height: 480px;"></p> |
| |
| <p>And here is what the XML layout looks like:</p> |
| |
| <pre><android.gesture.GestureOverlayView |
| xmlns:android="http://schemas.android.com/apk/res/android" |
| android:id="@+id/gestures" |
| android:layout_width="fill_parent" |
| android:layout_height="fill_parent" |
| |
| android:gestureStrokeType="multiple" |
| android:eventsInterceptionEnabled="true" |
| android:orientation="vertical"> |
| |
| <ListView |
| android:id="@android:id/list" |
| android:layout_width="fill_parent" |
| android:layout_height="fill_parent" /> |
| |
| </android.gesture.GestureOverlayView></pre> |
| |
| <p>In this application, the gestures view is an overlay on top of a regular |
| ListView. The overlay also specifies a few properties that we did not |
| need before:</p> |
| |
| <ul> |
| <li><code>gestureStrokeType</code>: indicates |
| whether we want to recognize gestures made of a single stroke or |
| multiple strokes. Since one of our gestures is the "+" symbol, we need |
| multiple strokes</li> |
| <li><code>eventsInterceptionEnabled</code>: when |
| set to true, this property tells the overlay to steal the events from |
| its children as soon as it knows the user is really drawing a gesture. |
| This is useful when there's a scrollable view under the overlay, to |
| avoid scrolling the underlying child as the user draws his gesture </li> |
| <li><code>orientation</code>: |
| indicates the scroll orientation of the views underneath. In this case |
| the list scrolls vertically, which means that any horizontal gestures |
| (like <code>action_delete</code>) can immediately be recognized as a |
| gesture. Gestures that start with a vertical stroke must contain at |
| least one horizontal component to be recognized. In other words, a |
| simple vertical line cannot be recognized as a gesture since it would |
| conflict with the list's scrolling.</li> |
| </ul> |
| |
| <p>The code used to load and set up the gestures library and overlay is exactly |
| the same as before. The only difference is that we now check the name of the |
| predictions to know what the user intended to do:</p> |
| |
| <pre>public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { |
| ArrayList<Prediction> predictions = mLibrary.recognize(gesture); |
| if (predictions.size() > 0 && predictions.get(0).score > 1.0) { |
| String action = predictions.get(0).name; |
| if ("action_add".equals(action)) { |
| Toast.makeText(this, "Adding a contact", Toast.LENGTH_SHORT).show(); |
| } else if ("action_delete".equals(action)) { |
| Toast.makeText(this, "Removing a contact", Toast.LENGTH_SHORT).show(); |
| } else if ("action_refresh".equals(action)) { |
| Toast.makeText(this, "Reloading contacts", Toast.LENGTH_SHORT).show(); |
| } |
| } |
| }</pre> |
| |
| <p>The user is now able to draw his gestures on top of the list without |
| interfering with the scrolling:</p> |
| |
| <img src="images/gestures_004.png" style="width: 320px; height: 480px;"> |
| |
| <p>The overlay even gives visual clues as to whether the gesture is considered |
| valid for recognition. In the case of a vertical overlay, for instance, |
| a single vertical stroke cannot be recognized as a gesture and is |
| therefore drawn with a translucent color:</p> |
| |
| <img src="images/gestures_003.png" style="width: 320px; height: 480px;"> |
| |
| <h3>It's your turn</h3> |
| |
| <p>Adding support for gestures in your application is easy and can be a valuable |
| addition. The gestures API does not even have to be used to recognize complex |
| shapes; it will work equally well to recognize simple swipes. We are very |
| excited by the possibilities the gestures API offers, and we're eager to see |
| what cool applications the community will create with it.</p> |