actionbar.jd revision cc0be914a9d8f733a82ecb22d56169a32492cb8f
1page.title=Action Bar
2page.tags="actionbar","menu","tabs"
3
4@jd:body
5
6
7<a class="notice-designers top" href="{@docRoot}design/patterns/actionbar.html">
8  <div>
9    <h3>Design Guide</h3>
10    <p>Action Bar</p>
11  </div>
12</a>
13
14<div id="qv-wrapper">
15<div id="qv">
16
17  <h2>In this document</h2>
18<ol>
19  <li><a href="#Adding">Adding the Action Bar</a>
20    <ol>
21      <li><a href="#Removing">Removing the action bar</a></li>
22      <li><a href="#Logo">Using a logo instead of an icon</a></li>
23    </ol>
24  </li>
25  <li><a href="#ActionItems">Adding Action Items</a>
26    <ol>
27      <li><a href="#ActionEvents">Handling clicks on action items</a></li>
28      <li><a href="#SplitBar">Using split action bar</a></li>
29    </ol>
30  </li>
31  <li><a href="#Home">Navigating Up with the App Icon</a></li>
32  <li><a href="#ActionView">Adding an Action View</a>
33    <ol>
34      <li><a href="#ActionViewCollapsing">Handling collapsible action views</a></li>
35    </ol>
36  </li>
37  <li><a href="#ActionProvider">Adding an Action Provider</a>
38    <ol>
39      <li><a href="#ShareActionProvider">Using the ShareActionProvider</a></li>
40      <li><a href="#CreatingActionProvider">Creating a custom action provider</a></li>
41    </ol>
42  </li>
43  <li><a href="#Tabs">Adding Navigation Tabs</a></li>
44  <li><a href="#Dropdown">Adding Drop-down Navigation</a></li>
45  <li><a href="#Style">Styling the Action Bar</a>
46    <ol>
47      <li><a href="#GeneralStyles">General appearance</a></li>
48      <li><a href="#ActionItemStyles">Action items</a></li>
49      <li><a href="#NavigationStyles">Navigation tabs</a></li>
50      <li><a href="#DropDownStyles">Drop-down lists</a></li>
51      <li><a href="#StyleExample">Example theme</a></li>
52    </ol>
53  </li>
54</ol>
55
56  <h2>Key classes</h2>
57  <ol>
58    <li>{@link android.support.v7.app.ActionBar}</li>
59    <li>{@link android.view.Menu}</li>
60  </ol>
61
62</div>
63</div>
64
65<p>The action bar is a window feature that identifies the user location, and
66provides user actions and navigation modes. Using the action bar offers your users a
67familiar interface across applications that the system gracefully adapts
68for different screen configurations.</p>
69
70<img src="{@docRoot}images/ui/actionbar@2x.png" alt="" width="428" height="215" />
71<p class="img-caption"><strong>Figure 1.</strong> An action bar that includes the [1] app icon,
72[2] two action items, and [3] action overflow.</p>
73
74<p>The action bar provides several key functions:</p>
75
76<ul>
77  <li>Provides a dedicated space for giving your app an identity and indicating the user's
78  location in the app.</li>
79  <li>Makes important actions prominent and accessible in a predictable way
80  (such as <em>Search</em>).</li>
81  <li>Supports consistent navigation and view switching within apps (with tabs or drop-down
82  lists).</li>
83</ul>
84
85<p>For more information about the action bar's interaction patterns and design guidelines,
86see the <a href="{@docRoot}design/patterns/actionbar.html">Action Bar</a>
87design guide.</p>
88
89<p>The {@link android.app.ActionBar} APIs were first added in Android 3.0 (API level 11) but they
90are also available in the <a href="{@docRoot}tools/support-library/index.html">Support Library</a>
91for compatibility with Android 2.1 (API level 7) and above.</p>
92
93<p><b>This guide focuses on how to use the
94support library's action bar</b>, but if your app supports <em>only</em> Android 3.0 or higher, you
95should use the {@link android.app.ActionBar} APIs in the framework. Most of the APIs are
96the same&mdash;but reside in a different package namespace&mdash;with a few exceptions to method
97names or signatures that are noted in the sections below.</p>
98
99
100<div class="caution">
101<p><strong>Caution:</strong> Be certain you import
102the {@code ActionBar} class (and related APIs) from the appropriate package:</p>
103<ul>
104<li>If supporting API levels <em>lower than</em> 11: <br>
105{@code import android.support.v7.app.ActionBar}</li>
106<li>If supporting <em>only</em> API level 11 and higher: <br>
107{@code import android.app.ActionBar}</li>
108</ul>
109</div>
110
111
112<p class="note"><strong>Note:</strong> If you're looking for information about the <em>contextual
113action bar</em> for displaying contextual action items, see the <a
114href="{@docRoot}guide/topics/ui/menus.html#context-menu">Menu</a> guide.</p>
115
116
117
118<h2 id="Adding">Adding the Action Bar</h2>
119
120<p>As mentioned above, this guide focuses on how to use the {@link
121android.support.v7.app.ActionBar} APIs in the support library. So before you can add the action
122bar, you must set up your project with the <strong>appcompat v7</strong> support library by
123following the instructions in the <a href="{@docRoot}tools/support-library/setup.html">Support
124Library Setup</a>.</p>
125
126<p>Once your project is set up with the support library, here's how to add the action bar:</p>
127<ol>
128  <li>Create your activity by extending {@link android.support.v7.app.ActionBarActivity}.</li>
129  <li>Use (or extend) one of the {@link android.support.v7.appcompat.R.style#Theme_AppCompat
130  Theme.AppCompat} themes for your activity. For example:
131  <pre>&lt;activity android:theme="@style/Theme.AppCompat.Light" ... ></pre>
132  </li>
133</ol>
134
135<p>Now your activity includes the action bar when running on Android 2.1 (API level 7) or higher.
136</p>
137
138<div class="note">
139<p><b>On API level 11 or higher</b></p>
140<p>The action bar is included in all activities that use the
141{@link android.R.style#Theme_Holo Theme.Holo} theme (or one of its
142descendants), which is the default theme when either the <a
143href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> or
144<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a>
145attribute is set to {@code "11"} or higher. If you don't want the action bar for an
146activity, set the activity theme to {@link android.R.style#Theme_Holo_NoActionBar
147Theme.Holo.NoActionBar}.</p>
148</div>
149
150
151<h3 id="Removing">Removing the action bar</h3>
152
153<p>You can hide the action bar at runtime by calling {@link android.support.v7.app.ActionBar#hide}.
154For example:</p>
155
156<pre>
157ActionBar actionBar = {@link android.support.v7.app.ActionBarActivity#getSupportActionBar()};
158actionBar.hide();
159</pre>
160
161<div class="note">
162<p><b>On API level 11 or higher</b></p>
163<p>Get the {@link android.app.ActionBar} with the {@link android.app.Activity#getActionBar}
164method.</p>
165</div>
166
167<p>When the action bar hides, the system adjusts your layout to fill the
168screen space now available. You can bring the action bar back by calling {@link
169android.support.v7.app.ActionBar#show()}.</p>
170
171<p>Beware that hiding and removing the action bar causes your activity to re-layout in order to
172account for the space consumed by the action bar. If your activity often hides and shows the
173action bar, you might want to enable <em>overlay mode</em>. Overlay mode
174draws the action bar in front of your activity layout, obscuring the top portion. This
175way, your layout remains fixed when the action bar hides and re-appears. To enable overlay mode,
176create a custom theme for your activity and set {@link
177android.support.v7.appcompat.R.attr#windowActionBarOverlay
178windowActionBarOverlay} to {@code true}. For more information, see the section below about <a
179href="#Style">Styling the Action Bar</a>.</p>
180
181
182<h3 id="Logo">Using a logo instead of an icon</h3>
183
184<p>By default, the system uses your application icon in the action bar, as specified by the <a
185href="{@docRoot}guide/topics/manifest/application-element.html#icon">{@code icon}</a>
186attribute in the <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code
187&lt;application&gt;}</a> or <a
188href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
189&lt;activity&gt;}</a> element. However, if you also specify the <a
190href="{@docRoot}guide/topics/manifest/application-element.html#logo">{@code logo}</a>
191attribute, then the action bar uses the logo image instead of the icon.</p>
192
193<p>A logo should usually be wider than the icon, but should not include unnecessary text. You
194should generally use a logo only when it represents your brand in a traditional format that users
195recognize. A good example is the YouTube app's logo&mdash;the logo represents the expected user
196brand, whereas the app's icon is a modified version that conforms to the square requirement
197for the launcher icon.</p>
198
199
200
201
202<h2 id="ActionItems">Adding Action Items</h2>
203
204<div class="figure" style="width:340px">
205  <img src="{@docRoot}images/ui/actionbar-item-withtext.png" width="340" alt="" />
206  <p class="img-caption"><strong>Figure 2.</strong> Action bar with three action buttons and
207the overflow button.</p>
208</div>
209
210<p>The action bar provides users access to the most important action
211items relating to the app's current
212context. Those that appear directly in the action bar with an icon and/or text are known
213as <em>action buttons</em>. Actions that can't fit in the action bar or aren't
214important enough are hidden in the action overflow.
215The user can reveal a list of the other actions by pressing the overflow button
216on the right side (or the device <em>Menu</em> button, if available).</p>
217
218<p>When your activity starts, the system populates the action items by calling your activity's
219{@link android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()} method. Use this
220method to inflate a <a
221href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a> that defines all the
222action items. For example, here's a menu resource defining a couple of menu items:</p>
223
224<p class="code-caption">res/menu/main_activity_actions.xml</p>
225<pre>
226&lt;menu xmlns:android="http://schemas.android.com/apk/res/android" >
227    &lt;item android:id="@+id/action_search"
228          android:icon="@drawable/ic_action_search"
229          android:title="@string/action_search"/&gt;
230    &lt;item android:id="@+id/action_compose"
231          android:icon="@drawable/ic_action_compose"
232          android:title="@string/action_compose" /&gt;
233&lt;/menu&gt;
234</pre>
235
236<p>Then in your activity's {@link android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()}
237method, inflate the menu resource into the given {@link android.view.Menu}
238to add each item to the action bar:</p>
239
240<pre>
241&#64;Override
242public boolean onCreateOptionsMenu(Menu menu) {
243    // Inflate the menu items for use in the action bar
244    MenuInflater inflater = getMenuInflater();
245    inflater.inflate(R.menu.main_activity_actions, menu);
246    return super.onCreateOptionsMenu(menu);
247}
248</pre>
249
250<p>To request that an item appear directly in the action bar
251as an action button, include {@code
252showAsAction="ifRoom"} in the {@code &lt;item&gt;} tag. For example:</p>
253
254<pre>
255&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"
256      <strong>xmlns:yourapp="http://schemas.android.com/apk/res-auto"</strong> >
257    &lt;item android:id="@+id/action_search"
258          android:icon="@drawable/ic_action_search"
259          android:title="@string/action_search"
260          <strong>yourapp:showAsAction="ifRoom"</strong>  /&gt;
261    ...
262&lt;/menu&gt;
263</pre>
264
265<p>If there's not enough room for the item in the action bar, it will appear in the action
266overflow.</p>
267
268
269<div class="note" id="XmlAttributes">
270<p><strong>Using XML attributes from the support library</strong></p>
271Notice that the {@code showAsAction} attribute above uses a custom namespace defined in the
272{@code &lt;menu>} tag. This is necessary when using any XML attributes defined by the support
273library, because these attributes do not exist in the Android framework on older devices.
274So you must use your own namespace as a prefix for all attributes defined by the support library.
275</p>
276</div>
277
278<p>If your menu item supplies both a title and an icon&mdash;with the {@code title} and
279{@code icon} attributes&mdash;then the action item shows only the icon by default. If you
280want to display the text title, add {@code "withText"} to the {@code showAsAction}
281attribute. For example:</p>
282
283<pre>
284&lt;item yourapp:showAsAction="ifRoom|withText" ... /&gt;
285</pre>
286
287<p class="note"><strong>Note:</strong> The {@code "withText"} value is a <em>hint</em> to the
288action bar that the text title should appear. The action bar will show the title when possible, but
289might not if an icon is available and the action bar is constrained for space.</p>
290
291<p>You should always define the {@code title} for each item even if you don't declare that
292the title appear with the action item, for the following reasons:</p>
293<ul>
294  <li>If there's not enough room in the action bar for the action item, the menu item appears
295in the overflow where only the title appears.</li>
296  <li>Screen readers for sight-impaired users read the menu item's title.</li>
297  <li>If the action item appears with only the icon, a user can long-press the item to reveal a
298tool-tip that displays the action title.</li>
299</ul>
300
301<p>The {@code icon} is optional, but recommended. For icon design recommendations,
302see the <a href="{@docRoot}design/style/iconography.html#action-bar">Iconography</a> design
303guide. You can also download a set of standard action bar icons (such as for Search or Discard)
304from the <a href="{@docRoot}design/downloads/index.html">Downloads</a> page.</p>
305
306<p>You can also use {@code "always"} to declare that an item always appear as an action button.
307However, you <strong>should not</strong> force an item to appear in the action bar this
308way. Doing so can create layout problems on devices with a narrow screen. It's best to instead
309use {@code "ifRoom"} to request that an item appear in the action bar, but allow the system to move
310it into the overflow when there's not enough room. However, it might be necessary to use this value
311if the item includes an <a href="#ActionView">action view</a> that cannot be collapsed and
312must always be visible to provide access to a critical feature.</p>
313
314
315
316
317<h3 id="ActionEvents">Handling clicks on action items</h3>
318
319<p>When the user presses an action, the system calls your activity's {@link
320android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} method. Using the
321{@link android.view.MenuItem} passed to this method, you can identify the action by calling {@link
322android.view.MenuItem#getItemId()}. This returns the unique ID provided by the {@code &lt;item&gt;}
323tag's {@code id} attribute so you can perform the appropriate action. For example:</p>
324
325<pre>
326&#64;Override
327public boolean onOptionsItemSelected(MenuItem item) {
328    // Handle presses on the action bar items
329    switch (item.getItemId()) {
330        case R.id.action_search:
331            openSearch();
332            return true;
333        case R.id.action_compose:
334            composeMessage();
335            return true;
336        default:
337            return super.onOptionsItemSelected(item);
338    }
339}
340</pre>
341
342<p class="note"><strong>Note:</strong> If you inflate menu items from a fragment, via the {@link
343android.app.Fragment} class's {@link android.app.Fragment#onCreateOptionsMenu onCreateOptionsMenu()}
344callback, the system calls {@link
345android.app.Fragment#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} for that
346fragment when the user selects one of those items. However, the activity gets a chance to
347handle the event first, so the system first calls {@link
348android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} on the activity,
349before calling the same callback for the fragment. To ensure that any fragments in the
350activity also have a chance to handle the callback, always pass the call to the superclass
351as the default behavior instead of returning {@code false} when you do not handle the item.</p>
352
353
354
355<div class="figure" style="width:420px;margin-top:0">
356<img src="{@docRoot}images/ui/actionbar-splitaction@2x.png" alt="" width="420"/>
357<p class="img-caption"><strong>Figure 3.</strong> Mock-ups showing an action bar with
358tabs (left), then with split action bar (middle); and with the app icon and title disabled
359(right).</p>
360</p>
361</div>
362
363<h3 id="SplitBar">Using split action bar</h3>
364
365<p>Split action bar provides a separate
366bar at the bottom of the screen to display all action items when the activity is running on
367a narrow screen (such as a portrait-oriented handset).</p>
368
369<p>Separating the action items this way
370ensures that a reasonable amount of space is available to display all your action
371items on a narrow screen, while leaving room for navigation and title elements at the top.</p>
372
373<p>To enable split action bar when using the support library, you must do two things:</p>
374<ol>
375  <li>Add {@code uiOptions="splitActionBarWhenNarrow"} to each
376<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
377element or to the
378<a href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>
379element. This attribute is understood only by API level 14 and higher (it is ignored
380by older versions).</li>
381  <li>To support older versions, add a <a
382  href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code &lt;meta-data>}</a>
383  element as a child of each
384  <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
385  element that declares the same value for {@code "android.support.UI_OPTIONS"}.</li>
386</ol>
387
388<p>For example:</p>
389
390<pre>
391&lt;manifest ...>
392    &lt;activity uiOptions="splitActionBarWhenNarrow" ... >
393        &lt;meta-data android:name="android.support.UI_OPTIONS"
394                   android:value="splitActionBarWhenNarrow" />
395    &lt;/activity>
396&lt;/manifest>
397</pre>
398
399
400<p>Using split action bar also allows <a href="#Tabs">navigation tabs</a> to collapse into the
401main action bar if you remove the icon and title (as shown on the right in figure 3).
402To create this effect, disable the action bar
403icon and title with {@link android.support.v7.app.ActionBar#setDisplayShowHomeEnabled
404setDisplayShowHomeEnabled(false)} and {@link
405android.support.v7.app.ActionBar#setDisplayShowTitleEnabled setDisplayShowTitleEnabled(false)}.</p>
406
407
408
409<h2 id="Home">Navigating Up with the App Icon</h2>
410
411<a class="notice-designers" href="{@docRoot}design/patterns/navigation.html">
412  <div>
413    <h3>Design Guide</h3>
414    <p>Navigation with Back and Up</p>
415  </div>
416</a>
417
418<div class="figure" style="width:240px">
419  <img src="{@docRoot}images/ui/actionbar-up.png" width="240" alt="" />
420  <p class="img-caption"><strong>Figure 4.</strong> The <em>Up</em> button in Gmail.</p>
421</div>
422
423<p>Enabling the app icon as an <em>Up</em> button allows the user to navigate your app based
424on the hierarchical relationships between screens. For instance, if screen A displays a list of
425items, and selecting an item leads to screen B, then
426screen B should include the <em>Up</em> button, which returns to screen A.</p>
427
428<p class="note"><strong>Note:</strong> Up navigation is distinct from the back navigation provided
429by the system <em>Back</em> button. The <em>Back</em> button is used to navigate in reverse
430chronological order through the history of screens the user has recently worked with. It is
431generally based on the temporal relationships between screens, rather than the app's hierarchy
432structure (which is the basis for up navigation).</p>
433
434<p>To enable the app icon as an <em>Up</em> button, call {@link
435android.support.v7.app.ActionBar#setDisplayHomeAsUpEnabled setDisplayHomeAsUpEnabled()}.
436For example:</p>
437
438<pre>
439&#64;Override
440protected void onCreate(Bundle savedInstanceState) {
441    super.onCreate(savedInstanceState);
442    setContentView(R.layout.activity_details);
443
444    ActionBar actionBar = getSupportActionBar();
445    actionBar.setDisplayHomeAsUpEnabled(true);
446    ...
447}
448</pre>
449
450<p>Now the icon in the action bar appears with the <em>Up</em> caret (as shown in figure 4).
451However, it won't do anything by default. To specify the activity to open when the
452user presses <em>Up</em> button, you have two options:</p>
453
454<ul>
455  <li><b>Specify the parent activity in the manifest file.</b>
456    <p>This is the best option when <strong>the parent activity is always the same</strong>. By
457declaring in the manifest which activity is the parent, the action bar automatically performs the
458correct action when the user presses the <em>Up</em> button.</p>
459
460    <p>Beginning in Android 4.1 (API level 16), you can declare the parent with the <a href=
461"{@docRoot}guide/topics/manifest/activity-element.html#parent">{@code parentActivityName}</a>
462attribute in the <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
463&lt;activity&gt;}</a> element.</p>
464    <p>To support older devices with the support library, also
465include a <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code
466&lt;meta-data&gt;}</a> element that specifies
467the parent activity as the value for {@code android.support.PARENT_ACTIVITY}. For example:</p>
468<pre>
469&lt;application ... >
470    ...
471    &lt;!-- The main/home activity (has no parent activity) -->
472    &lt;activity
473        android:name="com.example.myfirstapp.MainActivity" ...>
474        ...
475    &lt;/activity>
476    &lt;!-- A child of the main activity -->
477    &lt;activity
478        android:name="com.example.myfirstapp.DisplayMessageActivity"
479        android:label="&#64;string/title_activity_display_message"
480        android:parentActivityName="com.example.myfirstapp.MainActivity" >
481        &lt;!-- Parent activity meta-data to support API level 7+ -->
482        &lt;meta-data
483            android:name="android.support.PARENT_ACTIVITY"
484            android:value="com.example.myfirstapp.MainActivity" />
485    &lt;/activity>
486&lt;/application>
487</pre>
488
489  <p>Once the parent activity is specified in the manifest like this and you enable the <em>Up</em>
490  button with {@link
491android.support.v7.app.ActionBar#setDisplayHomeAsUpEnabled setDisplayHomeAsUpEnabled()}, your work
492is done and the action bar properly navigates up.</p>
493  </li>
494
495
496  <li><strong>Or, override {@link
497android.support.v7.app.ActionBarActivity#getSupportParentActivityIntent()} and {@link
498android.support.v7.app.ActionBarActivity#onCreateSupportNavigateUpTaskStack
499onCreateSupportNavigateUpTaskStack()} in your activity</strong>.</li>
500
501    <p>This is appropriate when <strong>the parent activity may be different</strong> depending
502    on how the user arrived at the current screen. That is, if there are many paths that the user
503    could have taken to reach the current screen, the <em>Up</em> button should navigate
504    backward along the path the user actually followed to get there.</p>
505
506    <p>The system calls {@link
507android.support.v7.app.ActionBarActivity#getSupportParentActivityIntent()} when the user presses
508the <em>Up</em> button while navigating your app (within your app's own task). If the activity that
509should open upon up navigation differs depending on how the user arrived at the current location,
510then you should override this method to return the {@link
511android.content.Intent} that starts the appropriate parent activity.</p>
512
513    <p>The system calls {@link
514android.support.v7.app.ActionBarActivity#onCreateSupportNavigateUpTaskStack
515onCreateSupportNavigateUpTaskStack()} for your activity when the user presses the <em>Up</em>
516button while your activity is running in a task that does <em>not</em> belong to your app. Thus,
517you must use the {@link android.support.v4.app.TaskStackBuilder} passed to this method to construct
518the appropriate back stack that should be synthesized when the user navigates up.</p>
519
520    <p>Even if you override {@link
521android.support.v7.app.ActionBarActivity#getSupportParentActivityIntent()} to specify up navigation
522as the user navigates your app, you can avoid the need to implement {@link
523android.support.v7.app.ActionBarActivity#onCreateSupportNavigateUpTaskStack
524onCreateSupportNavigateUpTaskStack()} by declaring "default" parent activities in the manifest file
525as shown above. Then the default implementation of {@link
526android.support.v7.app.ActionBarActivity#onCreateSupportNavigateUpTaskStack
527onCreateSupportNavigateUpTaskStack()} will synthesize a back stack based on the parent activities
528declared in the manifest.</p>
529
530  </li>
531</ul>
532
533<p class="note"><strong>Note:</strong>
534If you've built your app hierarchy using a series of fragments instead of multiple
535activities, then neither of the above options will work. Instead, to navigate up through your
536fragments, override {@link android.support.v7.app.ActionBarActivity#onSupportNavigateUp()}
537to perform the appropriate fragment transaction&mdash;usually by popping
538the current fragment from the back stack by calling {@link
539android.support.v4.app.FragmentManager#popBackStack()}.</p>
540
541<p>For more information about implementing <em>Up</em> navigation, read
542<a href="{@docRoot}training/implementing-navigation/ancestral.html">Providing Up Navigation</a>.</p>
543
544
545
546<h2 id="ActionView">Adding an Action View</h2>
547
548<div class="figure" style="width:340px">
549<img src="/images/ui/actionbar-searchview@2x.png" alt="" width="340" />
550<p class="img-caption"><strong>Figure 5.</strong> An action bar with a collapsible
551{@link android.support.v7.widget.SearchView}.</p>
552</div>
553
554
555<p>An <em>action view</em> is a widget that appears in the action bar as a substitute for an action
556button. An action view provides fast access to rich actions without changing activities or
557fragments, and without replacing the action bar. For example, if you have an action for Search, you
558can add an action view to
559embeds a {@link android.support.v7.widget.SearchView} widget in the action bar, as shown in figure
5605.</p>
561
562<p>To declare an action view, use either the {@code
563actionLayout} or {@code actionViewClass} attribute to specify either a layout
564resource or widget class to use, respectively. For example, here's how to add
565the {@link android.support.v7.widget.SearchView} widget:</p>
566
567<pre>
568&lt;?xml version="1.0" encoding="utf-8"?>
569&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"
570      xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
571    &lt;item android:id="@+id/action_search"
572          android:title="@string/action_search"
573          android:icon="@drawable/ic_action_search"
574          yourapp:showAsAction="ifRoom|collapseActionView"
575          <b>yourapp:actionViewClass="android.support.v7.widget.SearchView"</b> /&gt;
576&lt;/menu>
577</pre>
578
579<p>Notice that the {@code showAsAction} attribute also includes the {@code "collapseActionView"}
580value. This is optional and declares that the action view should be collapsed into a
581button. (This behavior is explained further in the following section about
582<a href="#ActionViewCollapsing">Handling collapsible action views</a>.)</p>
583
584<p>If you need to configure the action view (such as to add event listeners), you can do so during
585the {@link android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()} callback. You can
586acquire the action view object by calling the static method {@link
587android.support.v4.view.MenuItemCompat#getActionView MenuItemCompat.getActionView()} and passing it
588the corresponding {@link android.view.MenuItem}. For example, the search widget from the above
589sample is acquired like this:</p>
590
591
592<pre>
593&#64;Override
594public boolean onCreateOptionsMenu(Menu menu) {
595    getMenuInflater().inflate(R.menu.main_activity_actions, menu);
596    MenuItem searchItem = menu.findItem(R.id.action_search);
597    SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
598    // Configure the search info and add any event listeners
599    ...
600    return super.onCreateOptionsMenu(menu);
601}
602</pre>
603
604<div class="note">
605<p><b>On API level 11 or higher</b></p>
606<p>Get the action view by calling {@link android.view.MenuItem#getActionView} on the
607corresponding {@link android.view.MenuItem}:</p>
608<pre>menu.findItem(R.id.action_search).getActionView()</pre>
609</div>
610
611<p>For more information about using the search widget, see <a
612href="{@docRoot}guide/topics/search/search-dialog.html">Creating a Search Interface</a>.</p>
613
614
615
616<h3 id="ActionViewCollapsing">Handling collapsible action views</h3>
617
618<p>To preserve the action bar space, you can collapse your action view into an action button.
619When collapsed, the system might place the action
620into the action overflow, but the
621action view still appears in the action bar when the user selects it. You can make your action
622view collapsible by adding {@code "collapseActionView"} to the {@code showAsAction}
623attribute, as shown in the XML above.</p>
624
625<p>Because the system expands the action view when the user selects the action, you
626<em>do not</em> need to respond to the item in the {@link
627android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} callback. The system still calls
628{@link android.app.Activity#onOptionsItemSelected onOptionsItemSelected()}, but if
629you return {@code true} (indicating you've handled the event instead), then the
630action view will <em>not</em> expand.</p>
631
632<p>The system also collapses your action view when the user presses the <em>Up</em> button
633or <em>Back</em> button.</p>
634
635<p>If you need to update your activity based on the visibility of your action view, you can receive
636callbacks when the action is expanded and collapsed by defining an {@link
637android.support.v4.view.MenuItemCompat.OnActionExpandListener OnActionExpandListener} and
638passing it to {@link android.support.v4.view.MenuItemCompat#setOnActionExpandListener
639setOnActionExpandListener()}. For example:</p>
640
641
642<pre>
643&#64;Override
644public boolean onCreateOptionsMenu(Menu menu) {
645    getMenuInflater().inflate(R.menu.options, menu);
646    MenuItem menuItem = menu.findItem(R.id.actionItem);
647    ...
648
649    // When using the support library, the setOnActionExpandListener() method is
650    // static and accepts the MenuItem object as an argument
651    MenuItemCompat.setOnActionExpandListener(menuItem, new OnActionExpandListener() {
652        &#64;Override
653        public boolean onMenuItemActionCollapse(MenuItem item) {
654            // Do something when collapsed
655            return true;  // Return true to collapse action view
656        }
657
658        &#64;Override
659        public boolean onMenuItemActionExpand(MenuItem item) {
660            // Do something when expanded
661            return true;  // Return true to expand action view
662        }
663    });
664}
665</pre>
666
667
668
669
670<h2 id="ActionProvider">Adding an Action Provider</h2>
671
672<div class="figure" style="width:240px">
673  <img src="{@docRoot}images/ui/actionbar-shareaction@2x.png" alt="" width="240" />
674  <p class="img-caption"><strong>Figure 6.</strong> An action bar with
675  {@link android.widget.ShareActionProvider} expanded to show share targets.</p>
676</div>
677
678<p>Similar to an <a href="#ActionView">action view</a>, an <em>action provider</em>
679replaces an action button with a customized layout. However,
680unlike an action view, an action provider takes control of all the action's behaviors
681and an action provider can display a submenu when pressed.</p>
682
683<p>To declare an action provider, supply the {@code actionViewClass} attribute in the
684menu {@code &lt;item>} tag with a fully-qualified class name for an
685{@link android.support.v4.view.ActionProvider}.</p>
686
687<p>You can build your own action provider by extending the {@link
688android.support.v4.view.ActionProvider} class, but Android provides some pre-built action providers
689such as {@link android.support.v7.widget.ShareActionProvider}, which facilitates a "share" action
690by showing a list of possible apps for sharing directly in the action bar (as shown in figure
6916).</p>
692
693<p>Because each {@link android.support.v4.view.ActionProvider} class defines its own action
694behaviors, you don't need to listen for the action in the {@link
695android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} method. If necessary though,
696you can still listen for the click event in the {@link android.app.Activity#onOptionsItemSelected
697onOptionsItemSelected()} method in case you need to simultaneously perform another action. But be
698sure to return {@code false} so that the the action provider still receives the {@link
699android.support.v4.view.ActionProvider#onPerformDefaultAction()} callback to perform its intended
700action.</p>
701
702
703<p>However, if the action provider provides a submenu of actions, then your
704activity does not receive a call to {@link android.app.Activity#onOptionsItemSelected
705onOptionsItemSelected()} when the user opens the list or selects one of the submenu items.</p>
706
707
708
709<h3 id="ShareActionProvider">Using the ShareActionProvider</h3>
710
711<p>To add a "share" action with {@link android.support.v7.widget.ShareActionProvider},
712define the {@code actionProviderClass} for an {@code &lt;item&gt;} tag with
713the {@link android.support.v7.widget.ShareActionProvider} class. For example:</p>
714
715<pre>
716&lt;?xml version="1.0" encoding="utf-8"?>
717&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"
718      xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
719    &lt;item android:id="@+id/action_share"
720          android:title="@string/share"
721          yourapp:showAsAction="ifRoom"
722          <strong>yourapp:actionProviderClass="android.support.v7.widget.ShareActionProvider"</strong>
723          /&gt;
724    ...
725&lt;/menu>
726</pre>
727
728<p>Now the action provider takes control of the action item and handles both
729its appearance and behavior. But you must
730still provide a title for the item to be used when it appears in the action overflow.</p>
731
732<p>The only thing left to do is define
733the {@link android.content.Intent} you want to use for sharing. To do so, edit
734your {@link
735android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()} method to call {@link
736android.support.v4.view.MenuItemCompat#getActionProvider MenuItemCompat.getActionProvider()}
737and pass it the {@link android.view.MenuItem} holding the action provider. Then call {@link
738android.support.v7.widget.ShareActionProvider#setShareIntent setShareIntent()} on the
739returned {@link android.support.v7.widget.ShareActionProvider} and pass it an
740{@link android.content.Intent#ACTION_SEND} intent with the appropriate content attached.</p>
741
742<p>You should call {@link
743android.support.v7.widget.ShareActionProvider#setShareIntent setShareIntent()} once during {@link
744android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()} to initialize the share action,
745but because the user context might change, you must update the intent any time the shareable
746content changes by again calling {@link
747android.support.v7.widget.ShareActionProvider#setShareIntent setShareIntent()}.</p>
748
749<p>For example:</p>
750
751<pre>
752private ShareActionProvider mShareActionProvider;
753
754&#64;Override
755public boolean onCreateOptionsMenu(Menu menu) {
756    getMenuInflater().inflate(R.menu.main_activity_actions, menu);
757
758    // Set up ShareActionProvider's default share intent
759    MenuItem shareItem = menu.findItem(R.id.action_share);
760    mShareActionProvider = (ShareActionProvider)
761            MenuItemCompat.getActionProvider(shareItem);
762    mShareActionProvider.setShareIntent(getDefaultIntent());
763
764    return super.onCreateOptionsMenu(menu);
765}
766
767/** Defines a default (dummy) share intent to initialize the action provider.
768  * However, as soon as the actual content to be used in the intent
769  * is known or changes, you must update the share intent by again calling
770  * mShareActionProvider.{@link android.support.v7.widget.ShareActionProvider#setShareIntent setShareIntent()}
771  */
772private Intent getDefaultIntent() {
773    Intent intent = new Intent(Intent.ACTION_SEND);
774    intent.setType("image/*");
775    return intent;
776}
777</pre>
778
779<p>The {@link android.support.v7.widget.ShareActionProvider} now handles all user interaction with
780the item and you <em>do not</em> need to handle click events from the {@link
781android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} callback method.</p>
782
783
784<p>By default, the {@link android.support.v7.widget.ShareActionProvider} retains a ranking for each
785share target based on how often the user selects each one. The share targets used more frequently
786appear at the top of the drop-down list and the target used most often appears directly in the
787action bar as the default share target. By default, the ranking information is saved in a private
788file with a name specified by {@link
789android.support.v7.widget.ShareActionProvider#DEFAULT_SHARE_HISTORY_FILE_NAME}. If you use the
790{@link android.support.v7.widget.ShareActionProvider} or an extension of it for only one type of
791action, then you should continue to use this default history file and there's nothing you need to
792do. However, if you use {@link android.support.v7.widget.ShareActionProvider} or an extension of it
793for multiple actions with semantically different meanings, then each {@link
794android.support.v7.widget.ShareActionProvider} should specify its own history file in order to
795maintain its own history. To specify a different history file for the {@link
796android.support.v7.widget.ShareActionProvider}, call {@link
797android.support.v7.widget.ShareActionProvider#setShareHistoryFileName setShareHistoryFileName()}
798and provide an XML file name (for example, {@code "custom_share_history.xml"}).</p>
799
800
801<p class="note"><strong>Note:</strong> Although the {@link
802android.support.v7.widget.ShareActionProvider} ranks share targets based on frequency of use, the
803behavior is extensible and extensions of {@link android.support.v7.widget.ShareActionProvider} can
804perform different behaviors and ranking based on the history file (if appropriate).</p>
805
806
807
808
809<h3 id="CreatingActionProvider">Creating a custom action provider</h3>
810
811<p>Creating your own action provider allows you to re-use and manage dynamic action item
812behaviors in a self-contained module, rather than handle action item transformations and
813behaviors in your fragment or activity
814code. As shown in the previous section, Android already provides an implementation of {@link
815android.support.v4.view.ActionProvider} for share actions: the {@link
816android.support.v7.widget.ShareActionProvider}.</p>
817
818<p>To create your own action provider for a different action, simply extend the
819{@link android.support.v4.view.ActionProvider} class and implement
820its callback methods as appropriate. Most importantly, you should implement the following:</p>
821
822<dl>
823  <dt>{@link android.support.v4.view.ActionProvider#ActionProvider ActionProvider()}</dt>
824  <dd>This constructor passes you the application {@link android.content.Context}, which you
825should save in a member field to use in the other callback methods.</dd>
826
827  <dt>{@link android.support.v4.view.ActionProvider#onCreateActionView(MenuItem)}</dt>
828  <dd>This is where you define the action view for the item. Use the {@link
829android.content.Context} acquired from the constructor to instantiate a {@link
830android.view.LayoutInflater} and inflate your action view layout from an XML resource, then hook
831up event listeners. For example:
832<pre>
833public View onCreateActionView(MenuItem forItem) {
834    // Inflate the action view to be shown on the action bar.
835    LayoutInflater layoutInflater = LayoutInflater.from(mContext);
836    View view = layoutInflater.inflate(R.layout.action_provider, null);
837    ImageButton button = (ImageButton) view.findViewById(R.id.button);
838    button.setOnClickListener(new View.OnClickListener() {
839        &#064;Override
840        public void onClick(View v) {
841            // Do something...
842        }
843    });
844    return view;
845}
846</pre>
847</dd>
848
849  <dt>{@link android.support.v4.view.ActionProvider#onPerformDefaultAction()}</dt>
850  <dd>The system calls this when the menu item is selected from the action overflow and the
851action provider should perform a default action for the menu item.
852  <p>However, if your action provider provides a submenu, through the {@link
853android.support.v4.view.ActionProvider#onPrepareSubMenu onPrepareSubMenu()} callback, then the
854submenu appears even when the action provider is placed in the action overflow. Thus, {@link
855android.support.v4.view.ActionProvider#onPerformDefaultAction()} is never called when there is a
856submenu.</p>
857
858  <p class="note"><strong>Note:</strong> An activity or a fragment that implements {@link
859android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} can override the action
860provider's default behavior (unless it uses a submenu) by handling the item-selected event (and
861returning <code>true</code>), in which case, the system does not call {@link
862android.support.v4.view.ActionProvider#onPerformDefaultAction()}.</p>
863
864</dd>
865</dl>
866
867<p>For an example extension of {@link android.view.ActionProvider}, see <a
868href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/ActionBarSettingsActionProviderActivity.html"
869>ActionBarSettingsActionProviderActivity</a>.</p>
870
871
872
873
874<h2 id="Tabs">Adding Navigation Tabs</h2>
875
876<img src="{@docRoot}images/ui/actionbar-tabs@2x.png" width="760" alt="" />
877<p class="img-caption"><strong>Figure 7.</strong> Action bar tabs on a wide screen.</p>
878
879<a class="notice-designers" href="{@docRoot}design/building-blocks/tabs.html">
880  <div>
881    <h3>Design Guide</h3>
882    <p>Tabs</p>
883  </div>
884</a>
885
886<a class="notice-developers" href="{@docRoot}training/implementing-navigation/lateral.html">
887  <div>
888    <h3>Also read</h3>
889    <p>Creating Swipe Views with Tabs</p>
890  </div>
891</a>
892
893
894<div class="figure" style="width:240px">
895  <img src="{@docRoot}images/ui/actionbar-tabs-stacked@2x.png" width="240" alt="" />
896  <p class="img-caption"><strong>Figure 8.</strong> Tabs on a narrow screen.</p>
897</div>
898
899<p>Tabs in the action bar make it easy for users to explore and switch between different views in
900your app. The tabs provided by the {@link android.support.v7.app.ActionBar} are ideal because they
901adapt to different screen sizes. For example, when the screen is wide enough the tabs appear in the
902action bar alongside the action buttons (such as when on a tablet, shown in figure 7), while when
903on a narrow screen they appear in a separate bar (known as the "stacked action bar", shown in
904figure 8). In some cases, the Android system will instead show your tab items as a drop-down list
905to ensure the best fit in the action bar.</p>
906
907<p>To get started, your layout must include a {@link android.view.ViewGroup} in which you place
908each {@link android.app.Fragment} associated with a tab. Be sure the {@link android.view.ViewGroup}
909has a resource ID so you can reference it from your code and swap the tabs within it.
910Alternatively, if the tab content will fill the activity layout, then your activity doesn't need a
911layout at all (you don't even need to call {@link android.app.Activity#setContentView
912setContentView()}). Instead, you can place each fragment in the default root view, which you can
913refer to with the {@code android.R.id.content} ID.</p>
914
915
916<p>Once you determine where the fragments appear in the layout, the basic procedure to add tabs
917is:</p>
918<ol>
919  <li>Implement the {@link android.support.v7.app.ActionBar.TabListener} interface. This interface
920  provides callbacks for tab events, such as when the user presses one so you can swap the
921  tabs.</li>
922  <li>For each tab you want to add, instantiate an {@link android.support.v7.app.ActionBar.Tab}
923  and set the {@link android.support.v7.app.ActionBar.TabListener} by calling {@link
924  android.support.v7.app.ActionBar.Tab#setTabListener setTabListener()}. Also set the tab's title
925  and with {@link android.app.ActionBar.Tab#setText setText()} (and optionally, an icon with
926  {@link android.app.ActionBar.Tab#setIcon setIcon()}).</li>
927  <li>Then add each tab to the action bar by calling {@link android.support.v7.app.ActionBar#addTab
928  addTab()}.</li>
929</ol>
930
931<p>Notice that the {@link android.support.v7.app.ActionBar.TabListener}
932callback methods don't specify which fragment is associated with the tab, but merely which
933{@link android.support.v7.app.ActionBar.Tab} was selected.
934You must define your own association
935between each {@link android.app.ActionBar.Tab} and the appropriate {@link android.app.Fragment} that
936it represents. There are several ways you
937can define the association, depending on your design.</p>
938
939<p>For example, here's how you might implement the {@link android.app.ActionBar.TabListener}
940such that each tab uses its own instance of the listener:</p>
941<pre>
942public static class TabListener&lt;T extends Fragment> implements ActionBar.TabListener {
943    private Fragment mFragment;
944    private final Activity mActivity;
945    private final String mTag;
946    private final Class&lt;T> mClass;
947
948    /** Constructor used each time a new tab is created.
949      * @param activity  The host Activity, used to instantiate the fragment
950      * @param tag  The identifier tag for the fragment
951      * @param clz  The fragment's Class, used to instantiate the fragment
952      */
953    public TabListener(Activity activity, String tag, Class&lt;T> clz) {
954        mActivity = activity;
955        mTag = tag;
956        mClass = clz;
957    }
958
959    /* The following are each of the {@link android.app.ActionBar.TabListener} callbacks */
960
961    public void onTabSelected(Tab tab, FragmentTransaction ft) {
962        // Check if the fragment is already initialized
963        if (mFragment == null) {
964            // If not, instantiate and add it to the activity
965            mFragment = Fragment.instantiate(mActivity, mClass.getName());
966            ft.add(android.R.id.content, mFragment, mTag);
967        } else {
968            // If it exists, simply attach it in order to show it
969            ft.attach(mFragment);
970        }
971    }
972
973    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
974        if (mFragment != null) {
975            // Detach the fragment, because another one is being attached
976            ft.detach(mFragment);
977        }
978    }
979
980    public void onTabReselected(Tab tab, FragmentTransaction ft) {
981        // User selected the already selected tab. Usually do nothing.
982    }
983}
984</pre>
985
986<p class="caution"><strong>Caution:</strong> You <strong>must not</strong> call {@link
987android.app.FragmentTransaction#commit} for the fragment transaction in each of these
988callbacks&mdash;the system calls it for you and it may throw an exception if you call it yourself.
989You also <strong>cannot</strong> add these fragment transactions to the back stack.</p>
990
991<p>In this example, the listener simply attaches ({@link android.app.FragmentTransaction#attach
992attach()}) a fragment to the activity layout&mdash;or if not instantiated, creates the fragment and
993adds ({@link android.app.FragmentTransaction#add add()}) it to the layout (as a child of the {@code
994android.R.id.content} view group)&mdash;when the respective tab is selected, and detaches ({@link
995android.app.FragmentTransaction#detach detach()}) it when the tab is unselected.</p>
996
997<p>All that remains is to create each {@link android.app.ActionBar.Tab} and add it to the {@link
998android.app.ActionBar}. Additionally, you must call {@link
999android.app.ActionBar#setNavigationMode(int) setNavigationMode(NAVIGATION_MODE_TABS)} to make the
1000tabs visible.</p>
1001
1002<p>For example, the following code adds two tabs using the listener defined above:</p>
1003
1004<pre>
1005&#64;Override
1006protected void onCreate(Bundle savedInstanceState) {
1007    super.onCreate(savedInstanceState);
1008    // Notice that setContentView() is not used, because we use the root
1009    // android.R.id.content as the container for each fragment
1010
1011    // setup action bar for tabs
1012    ActionBar actionBar = getSupportActionBar();
1013    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
1014    actionBar.setDisplayShowTitleEnabled(false);
1015
1016    Tab tab = actionBar.newTab()
1017                       .setText(R.string.artist)
1018                       .setTabListener(new TabListener&lt;ArtistFragment>(
1019                               this, "artist", ArtistFragment.class));
1020    actionBar.addTab(tab);
1021
1022    tab = actionBar.newTab()
1023                   .setText(R.string.album)
1024                   .setTabListener(new TabListener&lt;AlbumFragment>(
1025                           this, "album", AlbumFragment.class));
1026    actionBar.addTab(tab);
1027}
1028</pre>
1029
1030
1031<p>If your activity stops, you should retain the currently selected tab with the <a href=
1032"{@docRoot}guide/components/activities.html#SavingActivityState">saved instance state</a> so you
1033can open the appropriate tab when the user returns. When it's time to save the state, you can query
1034the currently selected tab with {@link
1035android.support.v7.app.ActionBar#getSelectedNavigationIndex()}. This returns the index position of
1036the selected tab.</p>
1037
1038
1039<p class="caution"><strong>Caution:</strong> It's important that you save the state of each fragment
1040so when users switch fragments with the tabs and then return to a previous
1041fragment, it looks the way it did when they left. Some of the state is saved by default, but you
1042may need to manually save state for customized views. For information about saving the state of your
1043fragment, see the <a href="{@docRoot}guide/components/fragments.html">Fragments</a>
1044API guide.</p>
1045
1046<p class="note"><strong>Note:</strong> The above implementation for {@link
1047android.support.v7.app.ActionBar.TabListener} is one of several possible techniques. Another popular
1048option is to use {@link android.support.v4.view.ViewPager} to manage the fragments so users
1049can also use a swipe gesture to switch tabs. In this case, you simply tell the
1050{@link android.support.v4.view.ViewPager} the current tab position in the
1051{@link android.support.v7.app.ActionBar.TabListener#onTabSelected onTabSelected()} callback.
1052For more information, read
1053<a href="{@docRoot}training/implementing-navigation/lateral.html"
1054>Creating Swipe Views with Tabs</a>.</p>
1055
1056
1057
1058
1059
1060<h2 id="Dropdown">Adding Drop-down Navigation</h2>
1061
1062<div class="figure" style="width:240px">
1063  <img src="{@docRoot}images/ui/actionbar-dropdown@2x.png" alt="" width="240" />
1064  <p class="img-caption"><strong>Figure 9.</strong> A drop-down navigation list in the
1065action bar.</p>
1066</div>
1067
1068<p>As another mode of navigation (or filtering) for your activity, the action bar offers a built
1069in drop-down list (also known as a "spinner"). For example, the drop-down list can offer different
1070modes by which content in the activity is sorted.</p>
1071
1072<p>Using the drop-down list is useful when changing the content is important but not necessarily a
1073frequent occurrence. In cases where switching the content is more frequent,
1074you should use <a href="#Tabs">navigation tabs</a> instead.</p>
1075
1076
1077<p>The basic procedure to enable drop-down navigation is:</p>
1078
1079<ol>
1080  <li>Create a {@link android.widget.SpinnerAdapter} that provides the
1081list of selectable items for the drop-down and the layout to use when drawing each item in the
1082list.</li>
1083  <li>Implement {@link android.support.v7.app.ActionBar.OnNavigationListener} to define the
1084  behavior that occurs when the user selects an item from the list.</li>
1085  <li>During your activity's {@link android.app.Activity#onCreate
1086onCreate()} method, enable the action bar's drop-down list by calling {@link
1087android.support.v7.app.ActionBar#setNavigationMode setNavigationMode(NAVIGATION_MODE_LIST)}.
1088  </li>
1089  <li>Set the callback for the drop-down list with {@link
1090android.support.v7.app.ActionBar#setListNavigationCallbacks setListNavigationCallbacks()}.
1091For example:
1092<pre>
1093actionBar.setListNavigationCallbacks(mSpinnerAdapter, mNavigationCallback);
1094</pre>
1095<p>This method takes your {@link android.widget.SpinnerAdapter} and {@link
1096android.support.v7.app.ActionBar.OnNavigationListener}.</p>
1097</li>
1098</ol>
1099
1100<p>This procedure is relatively short, but implementing the {@link android.widget.SpinnerAdapter}
1101and {@link android.app.ActionBar.OnNavigationListener} is where most of the work is done. There are
1102many ways you can implement these to define the functionality for your drop-down navigation and
1103implementing various types of {@link android.widget.SpinnerAdapter} is beyond the scope of this
1104document (you should refer to the {@link android.widget.SpinnerAdapter} class reference for more
1105information). However, below is an example for a {@link android.widget.SpinnerAdapter} and {@link
1106android.app.ActionBar.OnNavigationListener} to get you started (click the title to reveal the
1107sample).</p>
1108
1109
1110
1111<div class="toggle-content closed">
1112
1113  <h3 id="Spinner"><a href="#" onclick="return toggleContent(this)">
1114    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img" alt="" />
1115    Example SpinnerAdapter and OnNavigationListener
1116  </a></h3>
1117
1118  <div class="toggle-content-toggleme">
1119
1120<p>{@link android.widget.SpinnerAdapter} is an adapter that provides data for a spinner widget,
1121such as the drop-down list in the action bar. {@link android.widget.SpinnerAdapter} is an interface
1122that you can implement, but Android includes some useful implementations that you can extend, such
1123as {@link android.widget.ArrayAdapter} and {@link
1124android.widget.SimpleCursorAdapter}. For example, here's an easy way to create a {@link
1125android.widget.SpinnerAdapter} by using {@link android.widget.ArrayAdapter} implementation, which
1126uses a string array as the data source:</p>
1127
1128<pre>
1129SpinnerAdapter mSpinnerAdapter = ArrayAdapter.createFromResource(this, R.array.action_list,
1130          android.R.layout.simple_spinner_dropdown_item);
1131</pre>
1132
1133<p>The {@link android.widget.ArrayAdapter#createFromResource createFromResource()} method takes
1134three parameters: the application {@link android.content.Context}, the resource ID for the string
1135array, and the layout to use for each list item.</p>
1136
1137<p>A <a href="{@docRoot}guide/topics/resources/string-resource.html#StringArray">string array</a>
1138defined in a resource looks like this:</p>
1139
1140<pre>
1141&lt;?xml version="1.0" encoding="utf-8"?&gt;
1142&lt;resources&gt;
1143    &lt;string-array name="action_list"&gt;
1144        &lt;item&gt;Mercury&lt;/item&gt;
1145        &lt;item&gt;Venus&lt;/item&gt;
1146        &lt;item&gt;Earth&lt;/item&gt;
1147    &lt;/string-array&gt;
1148&lt;/pre&gt;
1149</pre>
1150
1151<p>The {@link android.widget.ArrayAdapter} returned by {@link
1152android.widget.ArrayAdapter#createFromResource createFromResource()} is complete and ready for you
1153to pass it to {@link android.app.ActionBar#setListNavigationCallbacks setListNavigationCallbacks()}
1154(in step 4 from above). Before you do, though, you need to create the {@link
1155android.app.ActionBar.OnNavigationListener OnNavigationListener}.</p>
1156
1157
1158<p>Your implementation of {@link android.app.ActionBar.OnNavigationListener} is where you handle
1159fragment changes or other modifications to your activity when the user selects an item from the
1160drop-down list. There's only one callback method to implement in the listener: {@link
1161android.app.ActionBar.OnNavigationListener#onNavigationItemSelected onNavigationItemSelected()}.</p>
1162
1163<p>The {@link
1164android.app.ActionBar.OnNavigationListener#onNavigationItemSelected onNavigationItemSelected()}
1165method receives the position of the item in the list and a unique item ID provided by the {@link
1166android.widget.SpinnerAdapter}.</p>
1167
1168<p>Here's an example that instantiates an anonymous implementation of {@link
1169android.app.ActionBar.OnNavigationListener OnNavigationListener}, which inserts a {@link
1170android.app.Fragment} into the
1171layout container identified by {@code R.id.fragment_container}:</p>
1172
1173<pre>
1174mOnNavigationListener = new OnNavigationListener() {
1175  // Get the same strings provided for the drop-down's ArrayAdapter
1176  String[] strings = getResources().getStringArray(R.array.action_list);
1177
1178  &#64;Override
1179  public boolean onNavigationItemSelected(int position, long itemId) {
1180    // Create new fragment from our own Fragment class
1181    ListContentFragment newFragment = new ListContentFragment();
1182    FragmentTransaction ft = openFragmentTransaction();
1183    // Replace whatever is in the fragment container with this fragment
1184    //  and give the fragment a tag name equal to the string at the position selected
1185    ft.replace(R.id.fragment_container, newFragment, strings[position]);
1186    // Apply changes
1187    ft.commit();
1188    return true;
1189  }
1190};
1191</pre>
1192
1193<p>This instance of {@link android.app.ActionBar.OnNavigationListener OnNavigationListener} is
1194complete and you can now call {@link android.app.ActionBar#setListNavigationCallbacks
1195setListNavigationCallbacks()} (in step 4), passing the {@link android.widget.ArrayAdapter} and this
1196{@link android.app.ActionBar.OnNavigationListener OnNavigationListener}.</p>
1197
1198<p>In this example, when the user selects an item from the drop-down list, a fragment is added to
1199the layout (replacing the current fragment in the {@code R.id.fragment_container} view). The
1200fragment added is given a tag that uniquely identifies it, which is the same string used to
1201identify the fragment in the drop-down list.</p>
1202
1203<p>Here's a look at the {@code ListContentFragment} class that defines each fragment in this
1204example:</p>
1205
1206<pre>
1207public class ListContentFragment extends Fragment {
1208    private String mText;
1209
1210    &#64;Override
1211    public void onAttach(Activity activity) {
1212      // This is the first callback received; here we can set the text for
1213      // the fragment as defined by the tag specified during the fragment transaction
1214      super.onAttach(activity);
1215      mText = getTag();
1216    }
1217
1218    &#64;Override
1219    public View onCreateView(LayoutInflater inflater, ViewGroup container,
1220            Bundle savedInstanceState) {
1221        // This is called to define the layout for the fragment;
1222        // we just create a TextView and set its text to be the fragment tag
1223        TextView text = new TextView(getActivity());
1224        text.setText(mText);
1225        return text;
1226    }
1227}
1228</pre>
1229
1230  </div><!-- end toggle-content-toggleme -->
1231
1232</div><!-- end toggle-content -->
1233
1234
1235
1236
1237
1238
1239
1240<h2 id="Style">Styling the Action Bar</h2>
1241
1242<p>If you want to implement a visual design that represents your app's brand, the action bar allows
1243you to customize each detail of its appearance, including the action bar color, text colors, button
1244styles, and more. To do so, you need to use Android's <a href=
1245"{@docRoot}guide/topics/ui/themes.html">style and theme</a> framework to restyle the action bar
1246using special style properties.</p>
1247
1248<p class="caution"><strong>Caution:</strong> For all background drawables you provide, be sure to
1249use <a href="{@docRoot}guide/topics/graphics/2d-graphics.html#nine-patch">Nine-Patch drawables</a>
1250to allow stretching. The nine-patch image should be <em>smaller</em> than 40dp tall and 30dp
1251wide.</p>
1252
1253
1254
1255<h3 id="GeneralStyles">General appearance</h3>
1256
1257<dl>
1258  <dt>{@link android.R.attr#actionBarStyle
1259      actionBarStyle}</dt>
1260  <dd>Specifies a style resource that defines various style properties
1261  for the action bar.
1262      <p>The default for this style for this
1263      is {@link android.support.v7.appcompat.R.style#Widget_AppCompat_ActionBar
1264      Widget.AppCompat.ActionBar}, which is what you should use as the parent style.</p>
1265      <p>Supported styles include:</p>
1266    <dl>
1267      <dt>{@link android.R.attr#background}</dt>
1268        <dd>Defines a drawable resource for the action bar background.</dd>
1269      <dt>{@link android.R.attr#backgroundStacked}</dt>
1270        <dd>Defines a drawable resource for the stacked action bar
1271          (the <a href="#Tabs">tabs</a>).</dd>
1272      <dt>{@link android.R.attr#backgroundSplit}</dt>
1273        <dd>Defines a drawable resource for the <a href="#SplitBar">split action bar</a>.</dd>
1274      <dt>{@link android.R.attr#actionButtonStyle}</dt>
1275        <dd>Defines a style resource for action buttons.
1276          <p>The default for this style for this
1277      is {@link android.support.v7.appcompat.R.style#Widget_AppCompat_ActionButton
1278      Widget.AppCompat.ActionButton}, which is what you should use as the parent style.</p>
1279        </dd>
1280      <dt>{@link android.R.attr#actionOverflowButtonStyle}</dt>
1281        <dd>Defines a style resource for overflow action items.
1282          <p>The default for this style for this
1283      is {@link android.support.v7.appcompat.R.style#Widget_AppCompat_ActionButton_Overflow
1284      Widget.AppCompat.ActionButton.Overflow}, which is what you should use as the parent style.</p>
1285        </dd>
1286      <dt>{@link android.R.attr#displayOptions}</dt>
1287        <dd>Defines one or more action bar display options, such as whether to use the app logo,
1288        show the activity title, or enable the <em>Up</em> action. See {@link
1289        android.R.attr#displayOptions} for all possible values.
1290      <dt>{@link android.R.attr#divider}</dt>
1291        <dd>Defines a drawable resource for the divider between action items.</dd>
1292      <dt>{@link android.R.attr#titleTextStyle}</dt>
1293        <dd>Defines a style resource for the action bar title.
1294          <p>The default for this style for this
1295      is {@link android.support.v7.appcompat.R.style#TextAppearance_AppCompat_Widget_ActionBar_Title
1296      TextAppearance.AppCompat.Widget.ActionBar.Title}, which is what you should use as the parent
1297      style.</p></dd>
1298    </dl>
1299  </dd>
1300
1301  <dt>{@link android.R.attr#windowActionBarOverlay
1302      windowActionBarOverlay}</dt>
1303  <dd>Declares whether the action bar should overlay the activity layout rather than offset the
1304activity's layout position (for example, the Gallery app uses overlay mode). This is
1305{@code false} by default.
1306  <p>Normally, the action bar requires its own space on the screen and your activity layout fills in
1307what's left over. When the action bar is in overlay mode, your activity layout uses all the
1308available space and the system draws the action bar on top. Overlay mode can be useful if you want
1309your content to keep a fixed size and position when the action bar is hidden and shown. You might
1310also like to use it purely as a visual effect, because you can use a semi-transparent background
1311for the action bar so the user can still see some of your activity layout behind the action
1312bar.</p>
1313  <p class="note"><strong>Note:</strong> The {@link android.R.style#Theme_Holo Holo} theme families
1314draw the action bar with a semi-transparent background by default. However, you can modify it with
1315your own styles and the {@link android.R.style#Theme_DeviceDefault DeviceDefault} theme on
1316different devices might use an opaque background by default.</p>
1317  <p>When overlay mode is enabled, your activity layout has no awareness of the action bar lying on
1318top of it. So, you must be careful not to place any important information or UI components in the
1319area overlaid by the action bar. If appropriate, you can refer to the platform's value for {@link
1320android.R.attr#actionBarSize} to determine the height of the action bar, by referencing it
1321in your XML layout. For example:</p>
1322<pre>
1323&lt;SomeView
1324    ...
1325    android:layout_marginTop="?android:attr/actionBarSize" /&gt;
1326</pre>
1327  <p>You can also retrieve the action bar height at runtime with {@link
1328android.app.ActionBar#getHeight()}. This reflects the height of the action bar at the time it's
1329called, which might not include the stacked action bar (due to navigation tabs) if called during
1330early activity lifecycle methods. To see how you can determine the total height at runtime,
1331including the stacked action bar, see the <a href=
1332"{@docRoot}resources/samples/HoneycombGallery/src/com/example/android/hcgallery/TitlesFragment.html">
1333{@code TitlesFragment}</a> class in the <a href=
1334"{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery</a> sample app.</p>
1335
1336</dd>
1337
1338</dl>
1339
1340
1341<h3 id="ActionItemStyles">Action items</h3>
1342
1343<dl>
1344  <dt>{@link android.R.attr#actionButtonStyle
1345      actionButtonStyle}</dt>
1346  <dd>Defines a style resource for the action item buttons.
1347      <p>The default for this style for this
1348  is {@link android.support.v7.appcompat.R.style#Widget_AppCompat_ActionButton
1349  Widget.AppCompat.ActionButton}, which is what you should use as the parent style.</p></dd>
1350
1351  <dt>{@link android.R.attr#actionBarItemBackground
1352      actionBarItemBackground}</dt>
1353  <dd>Defines a drawable resource for each action item's background.
1354    This should be a <a href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList"
1355    >state-list drawable</a> to indicate different selected states.</dd>
1356
1357  <dt>{@link android.R.attr#itemBackground
1358      itemBackground}</dt>
1359  <dd>Defines a drawable resource for each action overflow item's background.
1360    This should be a <a href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList"
1361    >state-list drawable</a> to indicate different selected states.</dd>
1362
1363  <dt>{@link android.R.attr#actionBarDivider
1364      actionBarDivider}</dt>
1365  <dd>Defines a drawable resource for the divider between action items.</dd>
1366
1367  <dt>{@link android.R.attr#actionMenuTextColor
1368      actionMenuTextColor}</dt>
1369  <dd>Defines a color for text that appears in an action item.</dd>
1370
1371  <dt>{@link android.R.attr#actionMenuTextAppearance
1372      actionMenuTextAppearance}</dt>
1373  <dd>Defines a style resource for text that appears in an action item.</dd>
1374
1375  <dt>{@link android.R.attr#actionBarWidgetTheme
1376      actionBarWidgetTheme}</dt>
1377  <dd>Defines a theme resource for widgets that are inflated into the action bar as <a
1378href="#ActionView">action views</a>.</dd>
1379</dl>
1380
1381
1382<h3 id="NavigationStyles">Navigation tabs</h3>
1383
1384<dl>
1385  <dt>{@link android.R.attr#actionBarTabStyle
1386      actionBarTabStyle}</dt>
1387  <dd>Defines a style resource for tabs in the action bar.
1388      <p>The default for this style for this
1389  is {@link android.support.v7.appcompat.R.style#Widget_AppCompat_ActionBar_TabView
1390  Widget.AppCompat.ActionBar.TabView}, which is what you should use as the parent style.</p></dd>
1391
1392  <dt>{@link android.R.attr#actionBarTabBarStyle
1393      actionBarTabBarStyle}</dt>
1394  <dd>Defines a style resource for the thin bar that appears below the navigation tabs.
1395      <p>The default for this style for this
1396  is {@link android.support.v7.appcompat.R.style#Widget_AppCompat_ActionBar_TabBar
1397  Widget.AppCompat.ActionBar.TabBar}, which is what you should use as the parent style.</p></dd>
1398
1399  <dt>{@link android.R.attr#actionBarTabTextStyle
1400      actionBarTabTextStyle}</dt>
1401  <dd>Defines a style resource for text in the navigation tabs.
1402      <p>The default for this style for this
1403  is {@link android.support.v7.appcompat.R.style#Widget_AppCompat_ActionBar_TabText
1404  Widget.AppCompat.ActionBar.TabText}, which is what you should use as the parent style.</p></dd>
1405</dl>
1406
1407
1408<h3 id="DropDownStyles">Drop-down lists</h3>
1409
1410<dl>
1411  <dt>{@link android.R.attr#actionDropDownStyle
1412      actionDropDownStyle}</dt>
1413  <dd>Defines a style for the drop-down navigation (such as the background and text styles).
1414      <p>The default for this style for this
1415  is {@link android.support.v7.appcompat.R.style#Widget_AppCompat_Spinner_DropDown_ActionBar
1416  Widget.AppCompat.Spinner.DropDown.ActionBar}, which is what you should use as the parent
1417  style.</p></dd>
1418</dl>
1419
1420
1421<h3 id="StyleExample">Example theme</h3>
1422
1423<p>Here's an example that defines a custom theme for an activity, {@code CustomActivityTheme},
1424that includes several styles to customize the action bar.</p>
1425
1426<p>Notice that there are two version for each action bar style property. The first one
1427includes the {@code android:} prefix on the property name to support API levels 11 and higher
1428that include these properties in the framework. The second version does <em>not</em>
1429include the {@code android:} prefix and is for older versions of the platform, on which
1430the system uses the style property from the support library. The effect for each is the same.</p>
1431
1432<pre>
1433&lt;?xml version="1.0" encoding="utf-8"?>
1434&lt;resources>
1435    &lt;!-- the theme applied to the application or activity -->
1436    &lt;style name="CustomActionBarTheme"
1437           parent="&#64;style/Theme.AppCompat.Light">
1438        &lt;item name="android:actionBarStyle">&#64;style/MyActionBar&lt;/item>
1439        &lt;item name="android:actionBarTabTextStyle">&#64;style/TabTextStyle&lt;/item>
1440        &lt;item name="android:actionMenuTextColor">&#64;color/actionbar_text&lt;/item>
1441
1442        &lt;!-- Support library compatibility -->
1443        &lt;item name="actionBarStyle">&#64;style/MyActionBar&lt;/item>
1444        &lt;item name="actionBarTabTextStyle">&#64;style/TabTextStyle&lt;/item>
1445        &lt;item name="actionMenuTextColor">&#64;color/actionbar_text&lt;/item>
1446    &lt;/style>
1447
1448    &lt;!-- general styles for the action bar -->
1449    &lt;style name="MyActionBar"
1450           parent="&#64;style/Widget.AppCompat.ActionBar">
1451        &lt;item name="android:titleTextStyle">&#64;style/TitleTextStyle&lt;/item>
1452        &lt;item name="android:background">&#64;drawable/actionbar_background&lt;/item>
1453        &lt;item name="android:backgroundStacked">&#64;drawable/actionbar_background&lt;/item>
1454        &lt;item name="android:backgroundSplit">&#64;drawable/actionbar_background&lt;/item>
1455
1456        &lt;!-- Support library compatibility -->
1457        &lt;item name="titleTextStyle">&#64;style/TitleTextStyle&lt;/item>
1458        &lt;item name="background">&#64;drawable/actionbar_background&lt;/item>
1459        &lt;item name="backgroundStacked">&#64;drawable/actionbar_background&lt;/item>
1460        &lt;item name="backgroundSplit">&#64;drawable/actionbar_background&lt;/item>
1461    &lt;/style>
1462
1463    &lt;!-- action bar title text -->
1464    &lt;style name="TitleTextStyle"
1465           parent="&#64;style/TextAppearance.AppCompat.Widget.ActionBar.Title">
1466        &lt;item name="android:textColor">&#64;color/actionbar_text&lt;/item>
1467    &lt;/style>
1468
1469    &lt;!-- action bar tab text -->
1470    &lt;style name="TabTextStyle"
1471           parent="&#64;style/Widget.AppCompat.ActionBar.TabText">
1472        &lt;item name="android:textColor">&#64;color/actionbar_text&lt;/item>
1473    &lt;/style>
1474&lt;/resources>
1475
1476</pre>
1477
1478<p>In your manifest file, you can apply the theme to your entire app:</p>
1479
1480<pre>
1481&lt;application android:theme="&#64;style/CustomActionBarTheme" ... />
1482</pre>
1483
1484<p>Or to individual activities:</p>
1485
1486<pre>
1487&lt;activity android:theme="&#64;style/CustomActionBarTheme" ... />
1488</pre>
1489
1490
1491<p class="caution"><strong>Caution:</strong> Be certain that each theme and style declares a parent
1492theme in the {@code &lt;style&gt;} tag, from which it inherits all styles not explicitly declared
1493by your theme. When modifying the action bar, using a parent theme is important so that you can
1494simply override the action bar styles you want to change without re-implementing the styles you
1495want to leave alone (such as text size or padding in action items).</p>
1496
1497<p>For more information about using style and theme resources in your application, read <a
1498href="{@docRoot}guide/topics/ui/themes.html">Styles and Themes</a>.</p>
1499
1500
1501
1502