1 page.title=Gestures 2 parent.title=Articles 3 parent.link=../browser.html?tag=article 4 @jd:body 5 6 <p>Touch screens are a great way to interact with applications on 7 mobile devices. With a touch screen, users can easily tap, drag, fling, 8 or slide to quickly perform actions in their favorite applications. 9 For app developers. the Android framework makes it's easy to 10 recognize simple actions, like a swipe, but it has been more 11 difficult to handle complicated gestures, sometimes requiring 12 developers 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 15 in the new package {@link android.gesture}, lets you store, load, draw, and 16 recognize gestures. This article will show you how you can use the 17 <code>android.gesture</code> API in your applications. Before going any further, 18 you should <a 19 href="http://code.google.com/p/apps-for-android/downloads/detail?name= 20 GesturesDemos.zip&can=2&q=#makechanges">download the source code 21 of 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 26 on the emulator, called Gestures Builder. You can use this application to create 27 a set of pre-defined gestures for your own application. It also serves as an 28 example of how to let the user define his own gestures in your applications. You 29 can find the source code of Gestures Builders in the samples directory of each 30 SDK platform. In our example we will use Gestures Builder to generate a set of 31 gestures for us (make sure to create an AVD with an SD card image to use 32 Gestures Builder.) The screenshot below shows what the application looks like 33 after 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 38 important because it identifies each gesture within your application. The names 39 do not have to be unique. Actually it can be very useful to have several 40 gestures with the same name to increase the precision of the recognition. Every 41 time you add or edit a gesture in the Gestures Builder, a file is generated on 42 the emulator's SD card, <code>/sdcard/gestures</code>. This file contains the 43 description of all the gestures, and you will need to package it inside your 44 application 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 50 application. 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); 54 if (!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, 60 like the SD card, which is very important if you want your application to be 61 able to save the library; a library loaded from a raw resource is read-only and 62 cannot 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 69 is 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> 78 is not part of the usual android.widget package. Therefore, you must 79 use its fully qualified name. A gesture overlay acts as a simple 80 drawing board on which the user can draw his gestures. You can tweak 81 several visual properties, like the color and the width of the stroke 82 used to draw gestures, and register various listeners to follow what 83 the user is doing. The most commonly used listener is 84 <code>GestureOverlayView.OnGesturePerformedListener</code>, 85 which fires whenever a user is done drawing a gesture:</p> 86 87 <pre>GestureOverlayView gestures = (GestureOverlayView) findViewById(R.id.gestures); 88 gestures.addOnGesturePerformedListener(this);</pre> 89 90 <p>When the listener fires, you can ask the <code>GestureLibrary</code> 91 to try to recognize the gesture. In return, you will get a list of 92 Prediction instances, each with a name - the same name you entered in 93 the Gestures Builder - and a score. The list is sorted by descending 94 scores; the higher the score, the more likely the associated gesture is 95 the one the user intended to draw. The following code snippet 96 demonstrates 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 113 score is greater than 1.0. The threshold you use is entirely up to you 114 but know that scores lower than 1.0 are typically poor matches. And 115 this is all the code you need to create a simple application that can 116 recognize pre-defined gestures (see the source code of the project 117 GesturesDemo):</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 124 as a normal view, embedded inside a <code>LinearLayout</code>. 125 However, as its name suggests, it can also be used as an overlay on top 126 of other views. This can be useful to recognize gestures in a game or 127 just anywhere in the UI of an application. In the second example, 128 called GesturesListDemo, we'll create an overlay on top of a list of 129 contacts. We start again in Gestures Builder to create a new set of 130 pre-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 154 ListView. The overlay also specifies a few properties that we did not 155 need before:</p> 156 157 <ul> 158 <li><code>gestureStrokeType</code>: indicates 159 whether we want to recognize gestures made of a single stroke or 160 multiple strokes. Since one of our gestures is the "+" symbol, we need 161 multiple strokes</li> 162 <li><code>eventsInterceptionEnabled</code>: when 163 set to true, this property tells the overlay to steal the events from 164 its children as soon as it knows the user is really drawing a gesture. 165 This is useful when there's a scrollable view under the overlay, to 166 avoid scrolling the underlying child as the user draws his gesture </li> 167 <li><code>orientation</code>: 168 indicates the scroll orientation of the views underneath. In this case 169 the list scrolls vertically, which means that any horizontal gestures 170 (like <code>action_delete</code>) can immediately be recognized as a 171 gesture. Gestures that start with a vertical stroke must contain at 172 least one horizontal component to be recognized. In other words, a 173 simple vertical line cannot be recognized as a gesture since it would 174 conflict 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 178 the same as before. The only difference is that we now check the name of the 179 predictions 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 196 interfering 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 201 valid for recognition. In the case of a vertical overlay, for instance, 202 a single vertical stroke cannot be recognized as a gesture and is 203 therefore 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 210 addition. The gestures API does not even have to be used to recognize complex 211 shapes; it will work equally well to recognize simple swipes. We are very 212 excited by the possibilities the gestures API offers, and we're eager to see 213 what cool applications the community will create with it.</p> 214