1page.title=Gestures 2parent.title=Articles 3parent.link=../browser.html?tag=article 4@jd:body 5 6<p>Touch screens are a great way to interact with applications on 7mobile devices. With a touch screen, users can easily tap, drag, fling, 8or slide to quickly perform actions in their favorite applications. 9For app developers. the Android framework makes it's easy to 10recognize simple actions, like a swipe, but it has been more 11difficult to handle complicated gestures, sometimes requiring 12developers to write a lot of code.</p> 13 14<p>That's why we introduced a new gestures API in Android 1.6. This API, located 15in the new package {@link android.gesture}, lets you store, load, draw, and 16recognize gestures. This article will show you how you can use the 17<code>android.gesture</code> API in your applications. Before going any further, 18you should <a 19href="http://code.google.com/p/apps-for-android/downloads/detail?name= 20GesturesDemos.zip&can=2&q=#makechanges">download the source code 21of the examples</a>.</p> 22 23<h3>Creating a gestures library</h3> 24 25<p>Android 1.6 and higher SDK platforms include a new application pre-installed 26on the emulator, called Gestures Builder. You can use this application to create 27a set of pre-defined gestures for your own application. It also serves as an 28example of how to let the user define his own gestures in your applications. You 29can find the source code of Gestures Builders in the samples directory of each 30SDK platform. In our example we will use Gestures Builder to generate a set of 31gestures for us (make sure to create an AVD with an SD card image to use 32Gestures Builder.) The screenshot below shows what the application looks like 33after adding a few gestures:</p> 34 35<img src="images/gestures_006.png" style="width: 320px; height: 480px;"> 36 37<p>As you can see, a gesture is always associated with a name. That name is very 38important because it identifies each gesture within your application. The names 39do not have to be unique. Actually it can be very useful to have several 40gestures with the same name to increase the precision of the recognition. Every 41time you add or edit a gesture in the Gestures Builder, a file is generated on 42the emulator's SD card, <code>/sdcard/gestures</code>. This file contains the 43description of all the gestures, and you will need to package it inside your 44application inside the resources directory, in 45<code>/res/raw</code>.</p> 46 47<h3>Loading the gestures library</h3> 48 49<p>Now that you have a set of pre-defined gestures, you must load it inside your 50application. This can be achieved in several ways but the easiest is to use the 51<code>GestureLibraries</code> class:</p> 52 53<pre class="prettyprint">mLibrary = GestureLibraries.fromRawResource(this, R.raw.spells); 54if (!mLibrary.load()) { 55 finish(); 56}</pre> 57 58<p>In this example, the gesture library is loaded from the file 59<code>/res/raw/spells</code>. You can easily load libraries from other sources, 60like the SD card, which is very important if you want your application to be 61able to save the library; a library loaded from a raw resource is read-only and 62cannot be modified. The following diagram shows the structure of a library:</p> 63 64<img src="images/gestures_002.png" style="width: 600px; height: 512px;"> 65 66<h3>Recognizing gestures</h3> 67 68<p>To start recognizing gestures in your application, all you have to do 69is add a <code>GestureOverlayView</code> to your XML layout:</p> 70 71<pre><android.gesture.GestureOverlayView 72 android:id="@+id/gestures" 73 android:layout_width="fill_parent" 74 android:layout_height="0dip" 75 android:layout_weight="1.0" /></pre> 76 77<p>Notice that the <code>GestureOverlayView</code> 78is not part of the usual android.widget package. Therefore, you must 79use its fully qualified name. A gesture overlay acts as a simple 80drawing board on which the user can draw his gestures. You can tweak 81several visual properties, like the color and the width of the stroke 82used to draw gestures, and register various listeners to follow what 83the user is doing. The most commonly used listener is 84<code>GestureOverlayView.OnGesturePerformedListener</code>, 85which fires whenever a user is done drawing a gesture:</p> 86 87<pre>GestureOverlayView gestures = (GestureOverlayView) findViewById(R.id.gestures); 88gestures.addOnGesturePerformedListener(this);</pre> 89 90<p>When the listener fires, you can ask the <code>GestureLibrary</code> 91to try to recognize the gesture. In return, you will get a list of 92Prediction instances, each with a name - the same name you entered in 93the Gestures Builder - and a score. The list is sorted by descending 94scores; the higher the score, the more likely the associated gesture is 95the one the user intended to draw. The following code snippet 96demonstrates how to retrieve the name of the first prediction:</p> 97 98<pre>public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { 99 ArrayList<prediction> predictions = mLibrary.recognize(gesture); 100 101 // We want at least one prediction 102 if (predictions.size() > 0) { 103 Prediction prediction = predictions.get(0); 104 // We want at least some confidence in the result 105 if (prediction.score > 1.0) { 106 // Show the spell 107 Toast.makeText(this, prediction.name, Toast.LENGTH_SHORT).show(); 108 } 109 } 110}</pre> 111 112<p>In this example, the first prediction is taken into account only if it's 113score is greater than 1.0. The threshold you use is entirely up to you 114but know that scores lower than 1.0 are typically poor matches. And 115this is all the code you need to create a simple application that can 116recognize pre-defined gestures (see the source code of the project 117GesturesDemo):</p> 118 119<img src="images/gestures.png" style="width: 320px; height: 480px;"> 120 121<h3>Gestures overlay</h3> 122 123<p>In the example above, the <code>GestureOverlayView</code> was used 124as a normal view, embedded inside a <code>LinearLayout</code>. 125However, as its name suggests, it can also be used as an overlay on top 126of other views. This can be useful to recognize gestures in a game or 127just anywhere in the UI of an application. In the second example, 128called GesturesListDemo, we'll create an overlay on top of a list of 129contacts. We start again in Gestures Builder to create a new set of 130pre-defined gestures:</p> 131 132<p><img src="images/gestures_005.png" style="width: 320px; height: 480px;"></p> 133 134<p>And here is what the XML layout looks like:</p> 135 136<pre><android.gesture.GestureOverlayView 137 xmlns:android="http://schemas.android.com/apk/res/android" 138 android:id="@+id/gestures" 139 android:layout_width="fill_parent" 140 android:layout_height="fill_parent" 141 142 android:gestureStrokeType="multiple" 143 android:eventsInterceptionEnabled="true" 144 android:orientation="vertical"> 145 146 <ListView 147 android:id="@android:id/list" 148 android:layout_width="fill_parent" 149 android:layout_height="fill_parent" /> 150 151</android.gesture.GestureOverlayView></pre> 152 153<p>In this application, the gestures view is an overlay on top of a regular 154ListView. The overlay also specifies a few properties that we did not 155need before:</p> 156 157<ul> 158<li><code>gestureStrokeType</code>: indicates 159whether we want to recognize gestures made of a single stroke or 160multiple strokes. Since one of our gestures is the "+" symbol, we need 161multiple strokes</li> 162<li><code>eventsInterceptionEnabled</code>: when 163set to true, this property tells the overlay to steal the events from 164its children as soon as it knows the user is really drawing a gesture. 165This is useful when there's a scrollable view under the overlay, to 166avoid scrolling the underlying child as the user draws his gesture </li> 167<li><code>orientation</code>: 168indicates the scroll orientation of the views underneath. In this case 169the list scrolls vertically, which means that any horizontal gestures 170(like <code>action_delete</code>) can immediately be recognized as a 171gesture. Gestures that start with a vertical stroke must contain at 172least one horizontal component to be recognized. In other words, a 173simple vertical line cannot be recognized as a gesture since it would 174conflict with the list's scrolling.</li> 175</ul> 176 177<p>The code used to load and set up the gestures library and overlay is exactly 178the same as before. The only difference is that we now check the name of the 179predictions to know what the user intended to do:</p> 180 181<pre>public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { 182 ArrayList<Prediction> predictions = mLibrary.recognize(gesture); 183 if (predictions.size() > 0 && predictions.get(0).score > 1.0) { 184 String action = predictions.get(0).name; 185 if ("action_add".equals(action)) { 186 Toast.makeText(this, "Adding a contact", Toast.LENGTH_SHORT).show(); 187 } else if ("action_delete".equals(action)) { 188 Toast.makeText(this, "Removing a contact", Toast.LENGTH_SHORT).show(); 189 } else if ("action_refresh".equals(action)) { 190 Toast.makeText(this, "Reloading contacts", Toast.LENGTH_SHORT).show(); 191 } 192 } 193}</pre> 194 195<p>The user is now able to draw his gestures on top of the list without 196interfering with the scrolling:</p> 197 198<img src="images/gestures_004.png" style="width: 320px; height: 480px;"> 199 200<p>The overlay even gives visual clues as to whether the gesture is considered 201valid for recognition. In the case of a vertical overlay, for instance, 202a single vertical stroke cannot be recognized as a gesture and is 203therefore drawn with a translucent color:</p> 204 205<img src="images/gestures_003.png" style="width: 320px; height: 480px;"> 206 207<h3>It's your turn</h3> 208 209<p>Adding support for gestures in your application is easy and can be a valuable 210addition. The gestures API does not even have to be used to recognize complex 211shapes; it will work equally well to recognize simple swipes. We are very 212excited by the possibilities the gestures API offers, and we're eager to see 213what cool applications the community will create with it.</p> 214