• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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&amp;can=2&amp;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>&lt;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" /&gt;</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&lt;prediction&gt; predictions = mLibrary.recognize(gesture);
100
101    // We want at least one prediction
102    if (predictions.size() &gt; 0) {
103        Prediction prediction = predictions.get(0);
104        // We want at least some confidence in the result
105        if (prediction.score &gt; 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>&lt;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"&gt;
145
146    &lt;ListView
147        android:id="@android:id/list"
148        android:layout_width="fill_parent"
149        android:layout_height="fill_parent"  /&gt;
150
151&lt;/android.gesture.GestureOverlayView&gt;</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&lt;Prediction&gt; predictions = mLibrary.recognize(gesture);
183    if (predictions.size() &gt; 0 &amp;&amp; predictions.get(0).score &gt; 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