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