blob: fcaaed36da03b49c45796361588c1178f3f58b2a [file] [log] [blame]
Scott Mainabdf0d52011-02-08 10:20:27 -08001page.title=Creating a Search Interface
Joe Fernandez33baa5a2013-11-14 11:41:19 -08002page.tags=searchview
Scott Mainb3b2b4f2010-02-12 17:19:02 -08003@jd:body
4
5<div id="qv-wrapper">
6<div id="qv">
Scott Mainabdf0d52011-02-08 10:20:27 -08007
Scott Mainabdf0d52011-02-08 10:20:27 -08008
Scott Mainb3b2b4f2010-02-12 17:19:02 -08009<h2>In this document</h2>
10<ol>
Scott Main72e0df62011-06-23 12:02:10 -070011 <li><a href="#TheBasics">The Basics</a></li>
12 <li><a href="#SearchableConfiguration">Creating a Searchable Configuration</a></li>
13 <li><a href="#SearchableActivity">Creating a Searchable Activity</a>
14 <ol>
15 <li><a href="#DeclaringSearchableActivity">Declaring a searchable activity</a></li>
16 <li><a href="#PerformingSearch">Performing a search</a></li>
17 </ol>
18 </li>
19 <li><a href="#SearchDialog">Using the Search Dialog</a>
20 <ol>
21 <li><a href="#InvokingTheSearchDialog">Invoking the search dialog</a></li>
22 <li><a href="#LifeCycle">The impact of the search dialog on your activity lifecycle</a></li>
23 <li><a href="#SearchContextData">Passing search context data</a></li>
24 </ol>
25 </li>
26 <li><a href="#UsingSearchWidget">Using the Search Widget</a>
27 <ol>
28 <li><a href="#ConfiguringWidget">Configuring the search widget</a></li>
29 <li><a href="#WidgetFeatures">Other search widget features</a></li>
30 <li><a href="#UsingBoth">Using both the widget and the dialog</a></li>
31 </ol>
32 </li>
33 <li><a href="#VoiceSearch">Adding Voice Search</a></li>
34 <li><a href="#SearchSuggestions">Adding Search Suggestions</a></li>
Scott Mainb3b2b4f2010-02-12 17:19:02 -080035</ol>
Scott Main5e892d82010-05-25 17:04:01 -070036
37<h2>Key classes</h2>
38<ol>
39<li>{@link android.app.SearchManager}</li>
Scott Mainabdf0d52011-02-08 10:20:27 -080040<li>{@link android.widget.SearchView}</li>
Scott Main5e892d82010-05-25 17:04:01 -070041</ol>
42
Scott Mainec80d7f2010-09-24 16:17:27 -070043<h2>Related samples</h2>
Scott Main5e892d82010-05-25 17:04:01 -070044<ol>
45<li><a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable
46Dictionary</a></li>
Scott Mainabdf0d52011-02-08 10:20:27 -080047<li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/SearchViewActionBar.html">SearchView
48 in the Action Bar</a></li>
49<li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/SearchViewFilterMode.html">SearchView
50 filter mode</a></li>
Scott Main5e892d82010-05-25 17:04:01 -070051</ol>
52
53<h2>Downloads</h2>
54<ol>
Scott Main911711f2012-08-13 18:22:21 -070055<li><a href="{@docRoot}design/downloads/index.html#action-bar-icon-pack">Action Bar
56Icon Pack</a></li>
Scott Mainb3b2b4f2010-02-12 17:19:02 -080057</ol>
Scott Main5e892d82010-05-25 17:04:01 -070058
Scott Mainb3b2b4f2010-02-12 17:19:02 -080059</div>
60</div>
61
Scott Mainabdf0d52011-02-08 10:20:27 -080062<p>When you're ready to add search functionality to your application, Android helps you implement
63the user interface with either a search dialog that appears at the top of the activity window or a
64search widget that you can insert in your layout. Both the search dialog and the widget can deliver
65the user's search query to a specific activity in your application. This way, the user can initiate
66a search from any activity where the search dialog or widget is available, and the system starts the
67appropriate activity to perform the search and present results.</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -080068
Scott Mainabdf0d52011-02-08 10:20:27 -080069<p>Other features available for the search dialog and widget include:</p>
70
71<ul>
72 <li>Voice search</li>
73 <li>Search suggestions based on recent queries</li>
74 <li>Search suggestions that match actual results in your application data</li>
75</ul>
76
77<p>This guide shows you how to set up your application to provide a search interface
78that's assisted by the Android system to deliver search queries, using either the
79search dialog or the search widget.</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -080080
81
82<h2 id="TheBasics">The Basics</h2>
83
Scott Main5e892d82010-05-25 17:04:01 -070084<div class="figure" style="width:250px">
85<img src="{@docRoot}images/search/search-ui.png" alt="" height="417" />
86<p class="img-caption"><strong>Figure 1.</strong> Screenshot of an application's search dialog.</p>
87</div>
Scott Mainb3b2b4f2010-02-12 17:19:02 -080088
Scott Mainabdf0d52011-02-08 10:20:27 -080089<p>Before you begin, you should decide whether you'll implement your search interface using the
90search dialog or the search widget. Both provide the same search features, but in slightly different
91ways:</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -080092
Scott Mainabdf0d52011-02-08 10:20:27 -080093<ul>
94 <li>The <strong>search dialog</strong> is a UI component that's controlled by the Android system.
95When activated by the user, the search dialog appears at the top of the activity, as shown in figure
961.
97 <p>The Android system controls all events in the search dialog. When the user
98submits a query, the system delivers the query to the activity that you specify to
99handle searches. The dialog can also provide search suggestions while the user types.</p></li>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800100
Scott Mainabdf0d52011-02-08 10:20:27 -0800101 <li>The <strong>search widget</strong> is an instance of {@link android.widget.SearchView} that
102you can place anywhere in your layout. By default, the search widget behaves like a standard {@link
103android.widget.EditText} widget and doesn't do anything, but you can configure it so that the
104Android system handles all input events, delivers queries to the appropriate activity, and provides
105search suggestions (just like the search dialog). However, the search widget is available only in
106Android 3.0 (API Level 11) and higher.
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800107
Scott Mainabdf0d52011-02-08 10:20:27 -0800108<p class="note"><strong>Note:</strong> If you want, you can handle all user input into the
109search widget yourself, using various callback methods and listeners. This document, however,
110focuses on how to integrate the search widget with the system for an assisted search
111implementation. If you want to handle all user input yourself, read the reference documentation for
112{@link android.widget.SearchView} and its nested interfaces. </p></li>
113</ul>
114
115<p>When the user executes a search from the search dialog or a search widget, the system creates an
116{@link android.content.Intent} and stores the user query in it. The system then starts the activity
117that you've declared to handle searches (the "searchable activity") and delivers it the intent. To
118set up your application for this kind of assisted search, you need the following:</p>
119
120<ul>
121 <li>A searchable configuration
122 <p>An XML file that configures some settings for the search dialog or widget. It includes settings
123for features such as voice search, search suggestion, and hint text for the search box.</p></li>
124 <li>A searchable activity
125 <p>The {@link android.app.Activity} that receives the search query, searches your
126data, and displays the search results.</p></li>
127 <li>A search interface, provided by either:
128 <ul>
129 <li>The search dialog
Scott Main911711f2012-08-13 18:22:21 -0700130 <p>By default, the search dialog is hidden, but appears at the top of the screen when
131 you call {@link android.app.Activity#onSearchRequested()} (when the user presses your
132 Search button).</p>
Scott Mainabdf0d52011-02-08 10:20:27 -0800133 </li>
134 <li>Or, a {@link android.widget.SearchView} widget
135 <p>Using the search widget allows you to put the search box anywhere in your activity.
Scott Main911711f2012-08-13 18:22:21 -0700136Instead of putting it in your activity layout, you should usually use
137{@link android.widget.SearchView} as an
Scott Mainabdf0d52011-02-08 10:20:27 -0800138<a href="{@docRoot}guide/topics/ui/actionbar.html#ActionView">action view in the Action Bar</a>.</p>
139 </li>
140 </ul>
141 </li>
142</ul>
143
144<p>The rest of this document shows you how to create the searchable configuration, searchable
145activity, and implement a search interface with either the search dialog or search widget.</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800146
Scott Main5e892d82010-05-25 17:04:01 -0700147
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800148<h2 id="SearchableConfiguration">Creating a Searchable Configuration</h2>
149
Scott Mainabdf0d52011-02-08 10:20:27 -0800150<p>The first thing you need is an XML file called the searchable configuration. It configures
151certain UI aspects of the search dialog or widget and defines how features such as suggestions and
152voice search behave. This file is traditionally named {@code searchable.xml} and must be saved in
153the {@code res/xml/} project directory.</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800154
Scott Mainabdf0d52011-02-08 10:20:27 -0800155<p class="note"><strong>Note:</strong> The system uses this file to instantiate a {@link
156android.app.SearchableInfo} object, but you cannot create this object yourself at
157runtime&mdash;you must declare the searchable configuration in XML.</p>
158
159<p>The searchable configuration file must include the <a
160href="{@docRoot}guide/topics/search/searchable-config.html#searchable-element">{@code
161&lt;searchable&gt;}</a> element as the root node and specify one
162or more attributes. For example:</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800163
164<pre>
165&lt;?xml version="1.0" encoding="utf-8"?>
166&lt;searchable xmlns:android="http://schemas.android.com/apk/res/android"
Scott Main5e892d82010-05-25 17:04:01 -0700167 android:label="@string/app_label"
168 android:hint="@string/search_hint" >
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800169&lt;/searchable>
170</pre>
171
Scott Mainabdf0d52011-02-08 10:20:27 -0800172<p>The {@code android:label} attribute is the only required attribute. It points to a string
173resource, which should be the application name. This label isn't actually visible to the
174user until you enable search suggestions for Quick Search Box. At that point, this label is visible
175in the list of Searchable items in the system Settings.</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800176
Scott Main5e892d82010-05-25 17:04:01 -0700177<p>Though it's not required, we recommend that you always include the {@code android:hint}
Scott Mainabdf0d52011-02-08 10:20:27 -0800178attribute, which provides a hint string in the search box before users
179enters a query. The hint is important because it provides important clues to users about what
Scott Main5e892d82010-05-25 17:04:01 -0700180they can search.</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800181
182<p class="note"><strong>Tip:</strong> For consistency among other
183Android applications, you should format the string for {@code android:hint} as "Search
Scott Mainabdf0d52011-02-08 10:20:27 -0800184&lt;content-or-product&gt;". For example, "Search songs and artists" or "Search
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800185YouTube".</p>
186
Scott Mainabdf0d52011-02-08 10:20:27 -0800187<p>The <a
188href="{@docRoot}guide/topics/search/searchable-config.html#searchable-element">{@code
189&lt;searchable&gt;}</a> element accepts several other attributes. However, you don't need
190most attributes until you add features such as <a href="#SearchSuggestions">search suggestions</a>
191and <a href="#VoiceSearch">voice search</a>. For detailed information about the searchable
192configuration file, see the <a
193href="{@docRoot}guide/topics/search/searchable-config.html">Searchable Configuration</a> reference
194document.</p>
Scott Main5e892d82010-05-25 17:04:01 -0700195
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800196
197
198<h2 id="SearchableActivity">Creating a Searchable Activity</h2>
199
Scott Mainabdf0d52011-02-08 10:20:27 -0800200<p>A searchable activity is the {@link android.app.Activity} in your application that performs
201searches based on a query string and presents the search results.</p>
Scott Main5e892d82010-05-25 17:04:01 -0700202
Scott Mainabdf0d52011-02-08 10:20:27 -0800203<p>When the user executes a search in the search dialog or widget, the system starts your
204searchable activity and delivers it the search query in an {@link
205android.content.Intent} with the {@link android.content.Intent#ACTION_SEARCH} action. Your
206searchable activity retrieves the query from the intent's {@link android.app.SearchManager#QUERY
207QUERY} extra, then searches your data and presents the results.</p>
208
209<p>Because you may include the search dialog or widget in any other activity in your application,
210the system must know which activity is your searchable activity, so it can properly deliver the
211search query. So, you must first declare your searchable activity in the Android manifest file.</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800212
213
Scott Mainabdf0d52011-02-08 10:20:27 -0800214<h3 id="DeclaringSearchableActivity">Declaring a searchable activity</h3>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800215
Scott Mainabdf0d52011-02-08 10:20:27 -0800216<p>If you don't have one already, create an {@link android.app.Activity} that will perform
217searches and present results. You don't need to implement the search functionality yet&mdash;just
218create an activity that you can declare in the manifest. Inside the manifest's <a
219href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
220element:</p>
Scott Main5e892d82010-05-25 17:04:01 -0700221<ol>
Scott Mainabdf0d52011-02-08 10:20:27 -0800222 <li>Declare the activity to accept the {@link android.content.Intent#ACTION_SEARCH} intent, in an
223<a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
224&lt;intent-filter&gt;}</a>
Scott Main5e892d82010-05-25 17:04:01 -0700225element.</li>
Scott Mainabdf0d52011-02-08 10:20:27 -0800226 <li>Specify the searchable configuration to use, in a <a
Scott Main5e892d82010-05-25 17:04:01 -0700227href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code &lt;meta-data&gt;}</a>
228element.</li>
229</ol>
230
231<p>For example:</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800232
233<pre>
234&lt;application ... >
Scott Mainabdf0d52011-02-08 10:20:27 -0800235 &lt;activity android:name=".SearchableActivity" >
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800236 &lt;intent-filter>
237 &lt;action android:name="android.intent.action.SEARCH" />
238 &lt;/intent-filter>
239 &lt;meta-data android:name="android.app.searchable"
240 android:resource="@xml/searchable"/>
241 &lt;/activity>
242 ...
243&lt;/application>
244</pre>
245
Scott Main5e892d82010-05-25 17:04:01 -0700246<p>The {@code &lt;meta-data&gt;} element must include the {@code android:name} attribute with a
247value of {@code "android.app.searchable"} and the {@code android:resource} attribute with a
248reference to the searchable configuration file (in this example, it
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800249refers to the {@code res/xml/searchable.xml} file).</p>
250
Scott Mainabdf0d52011-02-08 10:20:27 -0800251<p class="note"><strong>Note:</strong> The <a
252href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
253&lt;intent-filter&gt;}</a> does not need a <a
Scott Main5e892d82010-05-25 17:04:01 -0700254href="{@docRoot}guide/topics/manifest/category-element.html">{@code &lt;category&gt;}</a> with the
Scott Mainabdf0d52011-02-08 10:20:27 -0800255{@code DEFAULT} value (which you usually see in <a
256href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a> elements),
257because the system delivers the {@link android.content.Intent#ACTION_SEARCH} intent explicitly to
258your searchable activity, using its component name.</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800259
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800260
261
262<h3 id="PerformingSearch">Performing a search</h3>
263
Scott Mainabdf0d52011-02-08 10:20:27 -0800264<p>Once you have declared your searchable activity in the manifest, performing a search in your
265searchable activity involves three steps:</p>
266
Scott Main5e892d82010-05-25 17:04:01 -0700267<ol>
268 <li><a href="#ReceivingTheQuery">Receiving the query</a></li>
269 <li><a href="#SearchingYourData">Searching your data</a></li>
270 <li><a href="#PresentingTheResults">Presenting the results</a></li>
271</ol>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800272
Scott Main5e892d82010-05-25 17:04:01 -0700273<p>Traditionally, your search results should be presented in a {@link android.widget.ListView}, so
Scott Mainabdf0d52011-02-08 10:20:27 -0800274you might want your searchable activity to extend {@link android.app.ListActivity}. It includes
275a default layout with a single {@link android.widget.ListView} and provides several
276convenience methods for working with the {@link android.widget.ListView}.</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800277
278
279<h4 id="ReceivingTheQuery">Receiving the query</h4>
280
Scott Mainabdf0d52011-02-08 10:20:27 -0800281<p>When a user executes a search from the search dialog or widget, the system starts your
282searchable activity and sends it a {@link android.content.Intent#ACTION_SEARCH} intent. This intent
283carries the search query in the
Scott Main5e892d82010-05-25 17:04:01 -0700284{@link android.app.SearchManager#QUERY QUERY} string extra. You must check for
Scott Mainabdf0d52011-02-08 10:20:27 -0800285this intent when the activity starts and extract the string. For example, here's how you can get the
286search query when your searchable activity starts:</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800287
288<pre>
289&#64;Override
290public void onCreate(Bundle savedInstanceState) {
291 super.onCreate(savedInstanceState);
292 setContentView(R.layout.search);
293
Scott Mainabdf0d52011-02-08 10:20:27 -0800294 // Get the intent, verify the action and get the query
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800295 Intent intent = getIntent();
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800296 if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
297 String query = intent.getStringExtra(SearchManager.QUERY);
298 doMySearch(query);
299 }
300}
301</pre>
302
303<p>The {@link android.app.SearchManager#QUERY QUERY} string is always included with
Scott Mainabdf0d52011-02-08 10:20:27 -0800304the {@link android.content.Intent#ACTION_SEARCH} intent. In this example, the query is
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800305retrieved and passed to a local {@code doMySearch()} method where the actual search operation
306is done.</p>
307
308
309<h4 id="SearchingYourData">Searching your data</h4>
310
Scott Main5e892d82010-05-25 17:04:01 -0700311<p>The process of storing and searching your data is unique to your application.
312You can store and search your data in many ways, but this guide does not show you how to store your
313data and search it. Storing and searching your data is something you should carefully consider in
Scott Mainabdf0d52011-02-08 10:20:27 -0800314terms of your needs and your data format. However, here are some tips you might be able to
315apply:</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800316
317 <ul>
318 <li>If your data is stored in a SQLite database on the device, performing a full-text search
Scott Mainabdf0d52011-02-08 10:20:27 -0800319(using FTS3, rather than a {@code LIKE} query) can provide a more robust search across text data and
320can produce results significantly faster. See <a href="http://sqlite.org/fts3.html">sqlite.org</a>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800321for information about FTS3 and the {@link android.database.sqlite.SQLiteDatabase} class for
322information about SQLite on Android. Also look at the <a
323href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable Dictionary</a> sample
324application to see a complete SQLite implementation that performs searches with FTS3.</li>
Scott Main5e892d82010-05-25 17:04:01 -0700325 <li>If your data is stored online, then the perceived search performance might be
326inhibited by the user's data connection. You might want to display a spinning progress wheel until
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800327your search returns. See {@link android.net} for a reference of network APIs and <a
Scott Mainabdf0d52011-02-08 10:20:27 -0800328href="{@docRoot}guide/topics/ui/dialogs.html#ProgressDialog">Creating a Progress Dialog</a>
329for information about how to display a progress wheel.</li>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800330 </ul>
331
332
333<div class="sidebox-wrapper">
334<div class="sidebox">
335<h2>About Adapters</h2>
Scott Mainabdf0d52011-02-08 10:20:27 -0800336<p>An {@link android.widget.Adapter} binds each item from a set of data into a
337{@link android.view.View} object. When the {@link android.widget.Adapter}
338is applied to a {@link android.widget.ListView}, each piece of data is inserted as an individual
339view into the list. {@link
340android.widget.Adapter} is just an interface, so implementations such as {@link
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800341android.widget.CursorAdapter} (for binding data from a {@link android.database.Cursor}) are needed.
Scott Mainabdf0d52011-02-08 10:20:27 -0800342If none of the existing implementations work for your data, then you can implement your own from
Scott Main5e892d82010-05-25 17:04:01 -0700343{@link android.widget.BaseAdapter}. Install the SDK Samples package for API Level 4 to see the
Scott Mainabdf0d52011-02-08 10:20:27 -0800344original version of the Searchable Dictionary, which creates a custom adapter to read data from
345a file.</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800346</div>
347</div>
348
349<p>Regardless of where your data lives and how you search it, we recommend that you return search
Scott Mainabdf0d52011-02-08 10:20:27 -0800350results to your searchable activity with an {@link android.widget.Adapter}. This way, you can easily
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800351present all the search results in a {@link android.widget.ListView}. If your data comes from a
Scott Mainabdf0d52011-02-08 10:20:27 -0800352SQLite database query, you can apply your results to a {@link android.widget.ListView}
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800353using a {@link android.widget.CursorAdapter}. If your data comes in some other type of format, then
Scott Mainabdf0d52011-02-08 10:20:27 -0800354you can create an extension of {@link android.widget.BaseAdapter}.</p>
355
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800356
357<h4 id="PresentingTheResults">Presenting the results</h4>
358
Scott Mainabdf0d52011-02-08 10:20:27 -0800359<p>As discussed above, the recommended UI for your search results is a {@link
360android.widget.ListView}, so you might want your searchable activity to extend {@link
361android.app.ListActivity}. You can then call {@link
362android.app.ListActivity#setListAdapter(ListAdapter) setListAdapter()}, passing it an {@link
Scott Main5e892d82010-05-25 17:04:01 -0700363android.widget.Adapter} that is bound to your data. This injects all the
Scott Mainabdf0d52011-02-08 10:20:27 -0800364search results into the activity {@link android.widget.ListView}.</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800365
Scott Mainabdf0d52011-02-08 10:20:27 -0800366<p>For more help presenting your results in a list, see the {@link android.app.ListActivity}
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800367documentation.</p>
368
369<p>Also see the <a
370href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable Dictionary</a> sample
Scott Main5e892d82010-05-25 17:04:01 -0700371for an a complete demonstration of how to search an SQLite database and use an
372{@link android.widget.Adapter} to provide results in a {@link android.widget.ListView}.</p>
373
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800374
375
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800376
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800377
Scott Mainabdf0d52011-02-08 10:20:27 -0800378<h2 id="SearchDialog">Using the Search Dialog</h2>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800379
Scott Mainabdf0d52011-02-08 10:20:27 -0800380<div class="sidebox-wrapper">
381<div class="sidebox">
382 <h2>Should I use the search dialog or the widget?</h2>
383 <p>The answer depends mostly on whether you are developing for Android 3.0 (API Level 11 or
384higher), because the {@link android.widget.SearchView} widget was introduced in Android 3.0. So,
385if you are developing your application for a version of Android lower than 3.0, the search widget is
386not an option and you should use the search dialog to implement your search interface.</p>
387 <p>If you <em>are</em> developing for Android 3.0 or higher, then the decision depends more on
388your needs. In most cases, we recommend that you use the search widget as an "action view" in the
389Action Bar. However, it might not be an option for you to put the search
390widget in the Action Bar for some reason (perhaps there's not enough space or you don't use the
391Action Bar). So, you might instead want to put the search widget somewhere in your activity layout.
392And if all else fails, you can still use the search dialog if you prefer to keep the search box
393hidden. In fact, you might want to offer both the dialog and the widget in some cases. For more
394information about the widget, skip to <a href="#UsingSearchWidget">Using the Search Widget</a>.</p>
395</div>
396</div>
397
398<p>The search dialog provides a floating search box at the top of the screen, with the application
399icon on the left. The search dialog can provide search suggestions as the user types and, when
400the user executes a search, the system sends the search query to a
401searchable activity that performs the search. However, if you are developing
402your application for devices running Android 3.0, you should consider using the search widget
403instead (see the side box).</p>
404
Scott Main911711f2012-08-13 18:22:21 -0700405<p>The search dialog is always hidden by default, until the user activates it. Your application
406can activate the search dialog by calling {@link
407android.app.Activity#onSearchRequested onSearchRequested()}. However, this method doesn't work
Scott Mainabdf0d52011-02-08 10:20:27 -0800408until you enable the search dialog for the activity.</p>
409
410<p>To enable the search dialog, you must indicate to the system which searchable activity should
411receive search queries from the search dialog, in order to perform searches. For example, in the
412previous section about <a href="#SearchableActivity">Creating a Searchable Activity</a>, a
413searchable activity named {@code SearchableActivity} was created. If you want a separate activity,
414named {@code OtherActivity}, to show the search dialog and deliver searches to {@code
415SearchableActivity}, you must declare in the manifest that {@code SearchableActivity} is the
416searchable activity to use for the search dialog in {@code OtherActivity}.</p>
417
418<p>To declare the searchable activity for an activity's search dialog,
419add a <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code &lt;meta-data&gt;}</a>
420element inside the respective activity's <a
421href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a> element.
422The <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code &lt;meta-data&gt;}</a>
423element must include the {@code android:value} attribute that specifies the searchable activity's
424class name and the {@code android:name} attribute with a value of {@code
425"android.app.default_searchable"}.</p>
426
427<p>For example, here is the declaration for
428both a searchable activity, {@code SearchableActivity}, and another activity, {@code
429OtherActivity}, which uses {@code SearchableActivity} to perform searches executed from its
430search dialog:</p>
431
432<pre>
433&lt;application ... >
434 &lt;!-- this is the searchable activity; it performs searches --&gt;
435 &lt;activity android:name=".SearchableActivity" >
436 &lt;intent-filter>
437 &lt;action android:name="android.intent.action.SEARCH" />
438 &lt;/intent-filter>
439 &lt;meta-data android:name="android.app.searchable"
440 android:resource="@xml/searchable"/>
441 &lt;/activity>
442
443 &lt;!-- this activity enables the search dialog to initiate searches
444 in the SearchableActivity --&gt;
445 &lt;activity android:name=".OtherActivity" ... >
446 &lt;!-- enable the search dialog to send searches to SearchableActivity -->
447 <b>&lt;meta-data android:name="android.app.default_searchable"
448 android:value=".SearchableActivity" /&gt;</b>
449 &lt;/activity>
450 ...
451&lt;/application>
452</pre>
453
454<p>Because the {@code OtherActivity} now includes a <a
455href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code &lt;meta-data&gt;}</a>
456element to declare which searchable activity to use for searches, the activity has enabled the
457search dialog.
Scott Main911711f2012-08-13 18:22:21 -0700458While the user is in this activity, the {@link
459android.app.Activity#onSearchRequested onSearchRequested()} method activates the search dialog.
Scott Mainabdf0d52011-02-08 10:20:27 -0800460When the user executes the search, the system starts {@code SearchableActivity} and delivers it
461the {@link android.content.Intent#ACTION_SEARCH} intent.</p>
462
463<p class="note"><strong>Note:</strong> The searchable activity itself provides the search dialog
464by default, so you don't need to add this declaration to {@code SearchableActivity}.</p>
465
466<p>If you want every activity in your application to provide the search dialog, insert the above <a
467href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code &lt;meta-data&gt;}</a>
468element as a child of the <a
469href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>
470element, instead of each <a
471href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>. This
472way, every activity inherits the value, provides the search dialog, and delivers searches to
473the same searchable activity. (If you have multiple searchable activities, you can override the
474default searchable activity by placing a different <a
475href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code &lt;meta-data&gt;}</a>
476declaration inside individual activities.)</p>
477
478<p>With the search dialog now enabled for your activities, your application is ready to perform
479searches.</p>
480
481
482<h3 id="InvokingTheSearchDialog">Invoking the search dialog</h3>
483
Scott Main911711f2012-08-13 18:22:21 -0700484<p>Although some devices provide a dedicated Search button, the behavior of the button may vary
485between devices and many devices do not provide a Search button at all. So when using the search
486dialog, you <strong>must provide a search button in your UI</strong> that activates the search
487dialog by calling {@link android.app.Activity#onSearchRequested()}.</p>
Scott Mainabdf0d52011-02-08 10:20:27 -0800488
Scott Main911711f2012-08-13 18:22:21 -0700489<p>For instance, you should add a Search button in your <a
490href="{@docRoot}guide/topics/ui/menus.html#options-menu">Options Menu</a> or UI
491layout that calls {@link android.app.Activity#onSearchRequested()}. For consistency with
492the Android system and other apps, you should label your button with the Android Search icon that's
493available from the <a href="{@docRoot}design/downloads/index.html#action-bar-icon-pack">Action Bar
494Icon Pack</a>.</p>
Scott Mainabdf0d52011-02-08 10:20:27 -0800495
Scott Main911711f2012-08-13 18:22:21 -0700496<p class="note"><strong>Note:</strong> If your app uses the <a
497href="{@docRoot}guide/topics/ui/actionbar.html">action bar</a>, then you should not use
498the search dialog for your search interface. Instead, use the <a href="#UsingSearchWidget">search
499widget</a> as a collapsible view in the action bar.</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800500
Scott Mainabdf0d52011-02-08 10:20:27 -0800501<p>You can also enable "type-to-search" functionality, which activates the search dialog when the
502user starts typing on the keyboard&mdash;the keystrokes are inserted into the search dialog. You can
503enable type-to-search in your activity by calling
Scott Main5e892d82010-05-25 17:04:01 -0700504{@link android.app.Activity#setDefaultKeyMode(int) setDefaultKeyMode}({@link
Scott Mainabdf0d52011-02-08 10:20:27 -0800505android.app.Activity#DEFAULT_KEYS_SEARCH_LOCAL}) during your activity's
Scott Main5e892d82010-05-25 17:04:01 -0700506{@link android.app.Activity#onCreate(Bundle) onCreate()} method.</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800507
508
Scott Mainabdf0d52011-02-08 10:20:27 -0800509<h3 id="LifeCycle">The impact of the search dialog on your activity lifecycle</h3>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800510
Scott Main5e892d82010-05-25 17:04:01 -0700511<p>The search dialog is a {@link android.app.Dialog} that floats at the top of the
Scott Mainabdf0d52011-02-08 10:20:27 -0800512screen. It does not cause any change in the activity stack, so when the search dialog appears, no
513lifecycle methods (such as {@link android.app.Activity#onPause()}) are called. Your activity just
514loses input focus, as input focus is given to the search dialog.
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800515</p>
516
Scott Mainabdf0d52011-02-08 10:20:27 -0800517<p>If you want to be notified when the search dialog is activated, override the {@link
518android.app.Activity#onSearchRequested()} method. When the system calls this method, it is an
519indication that your activity has lost input focus to the search dialog, so you can do any
520work appropriate for the event (such as pause
521a game). Unless you are <a
522href="#SearchContextData">passing search context data</a>
Scott Main5e892d82010-05-25 17:04:01 -0700523(discussed below), you should end the method by calling the super class implementation. For
524example:</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800525
526<pre>
527&#64;Override
528public boolean onSearchRequested() {
529 pauseSomeStuff();
530 return super.onSearchRequested();
531}
532</pre>
533
Scott Maincf9fe432012-01-31 19:14:35 -0800534<p>If the user cancels search by pressing the <em>Back</em> button, the search dialog closes and the
535activity
Scott Mainabdf0d52011-02-08 10:20:27 -0800536regains input focus. You can register to be notified when the search dialog is
Scott Main5e892d82010-05-25 17:04:01 -0700537closed with {@link android.app.SearchManager#setOnDismissListener(SearchManager.OnDismissListener)
538setOnDismissListener()}
539and/or {@link android.app.SearchManager#setOnCancelListener(SearchManager.OnCancelListener)
540setOnCancelListener()}. You
541should need to register only the {@link android.app.SearchManager.OnDismissListener
542OnDismissListener}, because it is called every time the search dialog closes. The {@link
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800543android.app.SearchManager.OnCancelListener OnCancelListener} only pertains to events in which the
Scott Main5e892d82010-05-25 17:04:01 -0700544user explicitly exited the search dialog, so it is not called when a search is executed (in which
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800545case, the search dialog naturally disappears).</p>
546
Scott Mainabdf0d52011-02-08 10:20:27 -0800547<p>If the current activity is not the searchable activity, then the normal activity lifecycle
548events are triggered once the user executes a search (the current activity receives {@link
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800549android.app.Activity#onPause()} and so forth, as
Scott Mainabdf0d52011-02-08 10:20:27 -0800550described in the <a
Scott Main50e990c2012-06-21 17:14:39 -0700551href="{@docRoot}guide/components/activities.html#Lifecycle">Activities</a>
Scott Mainabdf0d52011-02-08 10:20:27 -0800552document). If, however, the current activity is the searchable activity, then one of two
Scott Main5e892d82010-05-25 17:04:01 -0700553things happens:</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800554
Scott Main5e892d82010-05-25 17:04:01 -0700555<ol type="a">
Scott Mainabdf0d52011-02-08 10:20:27 -0800556 <li>By default, the searchable activity receives the {@link
557android.content.Intent#ACTION_SEARCH} intent with a call to {@link
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800558android.app.Activity#onCreate(Bundle) onCreate()} and a new instance of the
Scott Mainabdf0d52011-02-08 10:20:27 -0800559activity is brought to the top of the activity stack. There are now two instances of your
Scott Maincf9fe432012-01-31 19:14:35 -0800560searchable activity in the activity stack (so pressing the <em>Back</em> button goes back to the
561previous
Scott Mainabdf0d52011-02-08 10:20:27 -0800562instance of the searchable activity, rather than exiting the searchable activity).</li>
563 <li>If you set {@code android:launchMode} to <code>"singleTop"</code>, then the
564searchable activity receives the {@link android.content.Intent#ACTION_SEARCH} intent with a call
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800565to {@link android.app.Activity#onNewIntent(Intent)}, passing the new {@link
Scott Mainabdf0d52011-02-08 10:20:27 -0800566android.content.Intent#ACTION_SEARCH} intent here. For example, here's how you might handle
567this case, in which the searchable activity's launch mode is <code>"singleTop"</code>:
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800568<pre>
569&#64;Override
570public void onCreate(Bundle savedInstanceState) {
571 super.onCreate(savedInstanceState);
572 setContentView(R.layout.search);
573 handleIntent(getIntent());
574}
575
576&#64;Override
577protected void onNewIntent(Intent intent) {
578 setIntent(intent);
579 handleIntent(intent);
580}
581
582private void handleIntent(Intent intent) {
583 if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
584 String query = intent.getStringExtra(SearchManager.QUERY);
585 doMySearch(query);
586 }
587}
588</pre>
589
Scott Main369c1c12010-12-07 11:17:00 -0800590<p>Compared to the example code in the section about <a href="#PerformingSearch">Performing a
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800591Search</a>, all the code to handle the
Scott Mainabdf0d52011-02-08 10:20:27 -0800592search intent is now in the {@code handleIntent()} method, so that both {@link
Scott Main5e892d82010-05-25 17:04:01 -0700593android.app.Activity#onCreate(Bundle)
594onCreate()} and {@link android.app.Activity#onNewIntent(Intent) onNewIntent()} can execute it.</p>
595
Scott Mainabdf0d52011-02-08 10:20:27 -0800596<p>When the system calls {@link android.app.Activity#onNewIntent(Intent)}, the activity has
Scott Main5e892d82010-05-25 17:04:01 -0700597not been restarted, so the {@link android.app.Activity#getIntent()} method
Scott Mainabdf0d52011-02-08 10:20:27 -0800598returns the same intent that was received with {@link
Scott Main5e892d82010-05-25 17:04:01 -0700599android.app.Activity#onCreate(Bundle) onCreate()}. This is why you should call {@link
600android.app.Activity#setIntent(Intent)} inside {@link
Scott Mainabdf0d52011-02-08 10:20:27 -0800601android.app.Activity#onNewIntent(Intent)} (so that the intent saved by the activity is updated in
Scott Main5e892d82010-05-25 17:04:01 -0700602case you call {@link android.app.Activity#getIntent()} in the future).</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800603
604</li>
Scott Main5e892d82010-05-25 17:04:01 -0700605</ol>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800606
Scott Mainabdf0d52011-02-08 10:20:27 -0800607<p>The second scenario using <code>"singleTop"</code> launch mode is usually ideal, because chances
608are good that once a search is done, the user will perform additional searches and it's a bad
609experience if your application creates multiple instances of the searchable activity. So, we
610recommend that you set your searchable activity to <code>"singleTop"</code> launch mode in the
611application manifest. For example:</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800612
613<pre>
Scott Mainabdf0d52011-02-08 10:20:27 -0800614&lt;activity android:name=".SearchableActivity"
Scott Main5e892d82010-05-25 17:04:01 -0700615 <b>android:launchMode="singleTop"</b> >
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800616 &lt;intent-filter>
617 &lt;action android:name="android.intent.action.SEARCH" />
618 &lt;/intent-filter>
619 &lt;meta-data android:name="android.app.searchable"
620 android:resource="@xml/searchable"/>
621 &lt;/activity>
622</pre>
623
624
Scott Main5e892d82010-05-25 17:04:01 -0700625
Scott Mainabdf0d52011-02-08 10:20:27 -0800626<h3 id="SearchContextData">Passing search context data</h3>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800627
Scott Mainabdf0d52011-02-08 10:20:27 -0800628<p>In some cases, you can make necessary refinements to the search query inside the searchable
629activity, for every search made. However, if you want to refine your search criteria based on the
630activity from which the user is performing a search, you can provide additional data in the intent
631that the system sends to your searchable activity. You can pass the additional data in the {@link
632android.app.SearchManager#APP_DATA} {@link android.os.Bundle}, which is included in the {@link
633android.content.Intent#ACTION_SEARCH} intent.</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800634
Scott Mainabdf0d52011-02-08 10:20:27 -0800635<p>To pass this kind of data to your searchable activity, override the {@link
636android.app.Activity#onSearchRequested()} method for the activity from which the user can perform a
637search, create a {@link android.os.Bundle} with the additional data, and call {@link
638android.app.Activity#startSearch startSearch()} to activate the search dialog.
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800639For example:</p>
640
641<pre>
642&#64;Override
643public boolean onSearchRequested() {
644 Bundle appData = new Bundle();
Scott Mainabdf0d52011-02-08 10:20:27 -0800645 appData.putBoolean(SearchableActivity.JARGON, true);
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800646 startSearch(null, false, appData, false);
647 return true;
648 }
649</pre>
650
Scott Mainabdf0d52011-02-08 10:20:27 -0800651<p>Returning "true" indicates that you have successfully handled this callback event and
652called {@link android.app.Activity#startSearch startSearch()} to activate
653the search dialog. Once the user submits a query, it's delivered to your
654searchable activity along with the data you've added. You can extract the extra data from the {@link
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800655android.app.SearchManager#APP_DATA} {@link android.os.Bundle} to refine the search. For example:</p>
656
657<pre>
Scott Main5e892d82010-05-25 17:04:01 -0700658Bundle appData = getIntent().getBundleExtra(SearchManager.APP_DATA);
659if (appData != null) {
Scott Mainabdf0d52011-02-08 10:20:27 -0800660 boolean jargon = appData.getBoolean(SearchableActivity.JARGON);
Scott Main5e892d82010-05-25 17:04:01 -0700661}
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800662</pre>
663
Scott Main5e892d82010-05-25 17:04:01 -0700664<p class="caution"><strong>Caution:</strong> Never call the {@link
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800665android.app.Activity#startSearch(String,boolean,Bundle,boolean) startSearch()} method from outside
Scott Mainabdf0d52011-02-08 10:20:27 -0800666the {@link android.app.Activity#onSearchRequested()} callback method. To activate the search dialog
667in your activity, always call {@link android.app.Activity#onSearchRequested()}. Otherwise, {@link
Scott Main5e892d82010-05-25 17:04:01 -0700668android.app.Activity#onSearchRequested()} is not called and customizations (such as the addition of
669{@code appData} in the above example) are missed.</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800670
671
Scott Mainabdf0d52011-02-08 10:20:27 -0800672
673<h2 id="UsingSearchWidget">Using the Search Widget</h2>
674
675<div class="figure" style="width:429px;margin:0">
676 <img src="{@docRoot}images/ui/actionbar-actionview.png" alt="" />
677 <p class="img-caption"><strong>Figure 2.</strong> The {@link
678android.widget.SearchView} widget as an "action view" in the Action Bar.</p>
679</div>
680
681<p>The {@link android.widget.SearchView} widget is available in Android 3.0 and higher. If
682you're developing your application for Android 3.0 and have decided to use the search widget, we
683recommend that you insert the search widget as an <a
684href="{@docRoot}guide/topics/ui/actionbar.html#ActionView">action view in the Action Bar</a>,
685instead of using the search dialog (and instead of placing the search widget in your activity
686layout). For example, figure 2 shows the search widget in the Action Bar.</p>
687
688<p>The search widget provides the same functionality as the search dialog. It starts the appropriate
689activity when the user executes a search, and it can provide search suggestions and perform voice
690search.</p>
691
692<p class="note"><strong>Note:</strong> When you use the search widget as an action view, you
693still might need to support using the search dialog, for cases in which the search widget does
694not fit in the Action Bar. See the following section about <a href="#UsingBoth">Using both
695the widget and the dialog</a>.</p>
696
697
698<h3 id="ConfiguringWidget">Configuring the search widget</h3>
699
700<p>After you've created a <a href="#SearchableConfiguration">searchable configuration</a> and a <a
701href="#SearchableActivity">searchable activity</a>, as discussed above, you need to enable assisted
702search for each {@link android.widget.SearchView}. You can do so by calling {@link
703android.widget.SearchView#setSearchableInfo setSearchableInfo()} and passing it the {@link
704android.app.SearchableInfo} object that represents your searchable configuration.</p>
705
706<p>You can get a reference to the {@link android.app.SearchableInfo} by calling {@link
707android.app.SearchManager#getSearchableInfo getSearchableInfo()} on {@link
708android.app.SearchManager}.</p>
709
710<p>For example, if you're using a {@link android.widget.SearchView} as an action view in the <a
711href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a>, you should enable the widget
712during the {@link android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()} callback:</p>
713
714<pre>
715&#64;Override
716public boolean onCreateOptionsMenu(Menu menu) {
717 // Inflate the options menu from XML
718 MenuInflater inflater = getMenuInflater();
719 inflater.inflate(R.menu.options_menu, menu);
720
721 // Get the SearchView and set the searchable configuration
722 SearchManager searchManager = (SearchManager) {@link android.app.Activity#getSystemService getSystemService}(Context.SEARCH_SERVICE);
723 SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
kmccormick3b9f0aa2013-04-01 18:08:28 -0700724 // Assumes current activity is the searchable activity
Scott Mainabdf0d52011-02-08 10:20:27 -0800725 searchView.setSearchableInfo(searchManager.getSearchableInfo({@link android.app.Activity#getComponentName()}));
726 searchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default
727
728 return true;
729}
730</pre>
731
732<p>That's all you need. The search widget is now configured and the system will deliver search
733queries to your searchable activity. You can also enable <a href="#SearchSuggestions">search
734suggestions</a> for the search widget.</p>
735
736<p class="note"><strong>Note:</strong> If you want to handle all user input yourself, you can do so
737with some callback methods and event listeners. For more information, see the reference
738documentation for {@link android.widget.SearchView} and its nested interfaces for the
739appropriate event listeners.</p>
740
Scott Mainb10b48f2011-09-13 16:40:52 -0700741<p>For more information about action views in the Action Bar, read the <a
742href="{@docRoot}guide/topics/ui/actionbar.html#ActionView">Action Bar</a> developer guide (which
Scott Mainabdf0d52011-02-08 10:20:27 -0800743includes sample code for adding a search widget as an action view).</p>
744
745
746<h3 id="WidgetFeatures">Other search widget features</h3>
747
748<p>The {@link android.widget.SearchView} widget allows for a few additional features you might
749want:</p>
750
751<dl>
752 <dt>A submit button</dt>
753 <dd>By default, there's no button to submit a search query, so the user must press the
754"Return" key on the keyboard to initiate a search. You can add a "submit" button by calling
755{@link android.widget.SearchView#setSubmitButtonEnabled setSubmitButtonEnabled(true)}.</dd>
756 <dt>Query refinement for search suggestions</dt>
757 <dd>When you've enabled search suggestions, you usually expect users to simply select a
758suggestion, but they might also want to refine the suggested search query. You can add a button
759alongside each suggestion that inserts the suggestion in the search box for refinement by the
760user, by calling {@link android.widget.SearchView#setQueryRefinementEnabled
761setQueryRefinementEnabled(true)}.</dd>
762 <dt>The ability to toggle the search box visibility</dt>
763 <dd>By default, the search widget is "iconified," meaning that it is represented only by a
764search icon (a magnifying glass), and expands to show the search box when the user touches it.
765As shown above, you can show the search box by default, by calling {@link
766android.widget.SearchView#setIconifiedByDefault setIconifiedByDefault(false)}. You can also
767toggle the search widget appearance by calling {@link android.widget.SearchView#setIconified
768setIconified()}.</dd>
769</dl>
770
771<p>There are several other APIs in the {@link android.widget.SearchView} class that allow you to
772customize the search widget. However, most of them are used only when you handle all
773user input yourself, instead of using the Android system to deliver search queries and display
774search suggestions.</p>
775
776
777<h3 id="UsingBoth">Using both the widget and the dialog</h3>
778
779<p>If you insert the search widget in the Action Bar as an <a
780href="{@docRoot}guide/topics/ui/actionbar.html#ActionView">action view</a>, and you enable it to
781appear in the Action Bar "if there is room" (by setting {@code
782android:showAsAction="ifRoom"}), then there is a chance that the search widget will not appear
783as an action view, but the menu item will appear in the overflow menu. For example, when your
784application runs on a smaller screen, there might not be enough room in the Action Bar to display
785the search widget along with other action items or navigation elements, so the menu item will
786instead appear in the overflow menu. When placed in the overflow menu, the item works like an
787ordinary menu item and does not display the action view (the search widget).</p>
788
789<p>To handle this situation, the menu item to which you've attached the search widget should
790activate the search dialog when the user selects it from the overflow menu. In order for it to do
791so, you must implement {@link android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} to
792handle the "Search" menu item and open the search dialog by calling {@link
793android.app.Activity#onSearchRequested onSearchRequested()}.</p>
794
795<p>For more information about how items in the Action Bar work and how to handle this situation, see
Scott Mainb10b48f2011-09-13 16:40:52 -0700796the <a href="{@docRoot}guide/topics/ui/actionbar.html">Action
797Bar</a> developer guide.</p>
Scott Mainabdf0d52011-02-08 10:20:27 -0800798
799<p>Also see the <a
Scott Main19aad292011-10-18 16:57:32 -0700800href="{@docRoot}resources/samples/SearchableDictionary/src/com/example/android/searchabledict/SearchableDictionary.html"
801>Searchable Dictionary</a> for an example implementation using
Scott Mainabdf0d52011-02-08 10:20:27 -0800802both the dialog and the widget.</p>
803
804
805
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800806<h2 id="VoiceSearch">Adding Voice Search</h2>
807
Scott Mainabdf0d52011-02-08 10:20:27 -0800808<p>You can add voice search functionality to your search dialog or widget by adding the {@code
Scott Main5e892d82010-05-25 17:04:01 -0700809android:voiceSearchMode} attribute to your searchable configuration. This adds a voice search
Scott Mainabdf0d52011-02-08 10:20:27 -0800810button that launches a voice prompt. When the user
Scott Main5e892d82010-05-25 17:04:01 -0700811has finished speaking, the transcribed search query is sent to your searchable
Scott Mainabdf0d52011-02-08 10:20:27 -0800812activity.</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800813
Scott Main5e892d82010-05-25 17:04:01 -0700814<p>For example:</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800815
816<pre>
817&lt;?xml version="1.0" encoding="utf-8"?>
818&lt;searchable xmlns:android="http://schemas.android.com/apk/res/android"
819 android:label="@string/search_label"
820 android:hint="@string/search_hint"
Scott Main5e892d82010-05-25 17:04:01 -0700821 <b>android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"</b> >
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800822&lt;/searchable>
823</pre>
824
825<p>The value {@code showVoiceSearchButton} is required to enable voice
826search, while the second value, {@code launchRecognizer}, specifies that the voice search button
Scott Mainabdf0d52011-02-08 10:20:27 -0800827should launch a recognizer that returns the transcribed text to the searchable activity.</p>
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800828
Scott Main5e892d82010-05-25 17:04:01 -0700829<p>You can provide additional attributes to specify the voice search behavior, such
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800830as the language to be expected and the maximum number of results to return. See the <a
Scott Main5e892d82010-05-25 17:04:01 -0700831href="searchable-config.html">Searchable Configuration</a> reference for more information about the
Scott Mainb3b2b4f2010-02-12 17:19:02 -0800832available attributes.</p>
833
834<p class="note"><strong>Note:</strong> Carefully consider whether voice search is appropriate for
Scott Main5e892d82010-05-25 17:04:01 -0700835your application. All searches performed with the voice search button are immediately sent to
Scott Mainabdf0d52011-02-08 10:20:27 -0800836your searchable activity without a chance for the user to review the transcribed query. Sufficiently
Scott Main5e892d82010-05-25 17:04:01 -0700837test the voice recognition and ensure that it understands the types of queries that
838the user might submit inside your application.</p>
Scott Mainabdf0d52011-02-08 10:20:27 -0800839
840
841
842<h2 id="SearchSuggestions">Adding Search Suggestions</h2>
843
844<div class="figure" style="width:250px;margin:0">
845<img src="{@docRoot}images/search/search-suggest-custom.png" alt="" height="417" />
846<p class="img-caption"><strong>Figure 3.</strong> Screenshot of a search dialog with custom
847search suggestions.</p>
848</div>
849
850<p>Both the search dialog and the search widget can provide search suggestions as the user
851types, with assistance from the Android system. The system manages the list of suggestions and
852handles the event when the user selects a suggestion.</p>
853
854<p>You can provide two kinds of search suggestions:</p>
855
856<dl>
857 <dt>Recent query search suggestions</dt>
858 <dd>These suggestions are simply words that the user previously used as search queries in
859your application.
860 <p>See <a href="adding-recent-query-suggestions.html">Adding Recent Query
861Suggestions</a>.</p></dd>
862 <dt>Custom search suggestions</dt>
863 <dd>These are search suggestions that you provide from your own data source, to help users
864immediately select the correct spelling or item they are searching for. Figure 3 shows an
865example of custom suggestions for a dictionary application&mdash;the user can select a suggestion
866to instantly go to the definition.
867 <p>See <a href="adding-custom-suggestions.html">Adding Custom
868Suggestions</a></p></dd>
869</dl>
870