• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Action Bar
2parent.title=User Interface
3parent.link=index.html
4@jd:body
5
6<div id="qv-wrapper">
7<div id="qv">
8
9  <h2>Quickview</h2>
10  <ul>
11    <li>A replacement for the title bar that includes the application icon and activity title</li>
12    <li>Provides action items from the Options Menu and modes of navigating around the
13application</li>
14    <li>Supports custom views, including an embedded search box</li>
15    <li>Requires API Level 11</li>
16  </ul>
17
18  <h2>In this document</h2>
19  <ol>
20    <li><a href="#Adding">Adding the Action Bar</a>
21      <ol>
22        <li><a href="#Removing">Removing the Action Bar</a></li>
23      </ol>
24    </li>
25    <li><a href="#ActionItems">Adding Action Items</a>
26      <ol>
27        <li><a href="#Home">Using the app icon as an action item</a></li>
28      </ol>
29    </li>
30    <li><a href="#ActionView">Adding an Action View</a></li>
31    <li><a href="#Tabs">Adding Tabs</a></li>
32    <li><a href="#Dropdown">Adding Drop-down Navigation</a></li>
33    <li><a href="#Style">Styling the Action Bar</a></li>
34  </ol>
35
36  <h2>Key classes</h2>
37  <ol>
38    <li>{@link android.app.ActionBar}</li>
39    <li>{@link android.view.Menu}</li>
40  </ol>
41
42  <h2>Related samples</h2>
43  <ol>
44    <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/index.html#ActionBar">API
45        Demos</a></li>
46    <li><a
47href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery</a></li>
48  </ol>
49
50  <h2>See also</h2>
51  <ol>
52    <li><a href="{@docRoot}guide/topics/ui/menus.html">Menus</a></li>
53  </ol>
54</div>
55</div>
56
57<p>The Action Bar is a widget for activities that replaces the traditional title bar at
58the top of the screen. By default, the Action Bar includes the application logo on the left side,
59followed by the activity title, and any available items from the Options Menu on the right side. The
60Action Bar offers several useful features, including the ability to:</p>
61
62<ul>
63  <li>Display items from the <a
64href="{@docRoot}guide/topics/ui/menus.html#OptionsMenu">Options Menu</a> directly in the Action
65Bar, as "action
66items"&mdash;providing instant access to key user actions.
67    <p>Menu items that do not appear as action items are placed in the overflow menu, revealed
68by a drop-down list in the Action Bar.</p></li>
69  <li>Provide tabs for navigating between <a
70href="{@docRoot}guide/topics/fundamentals/fragments.html">fragments</a>.</li>
71  <li>Provide a drop-down list for navigation.</li>
72  <li>Provide interactive "action views" in place of action items (such as a search box).</li>
73</ul>
74
75<img src="{@docRoot}images/ui/actionbar.png" height="36" alt="" />
76
77<p class="img-caption"><strong>Figure 1.</strong> A screenshot of the Action Bar in the Email
78application, containing action items to compose new email and refresh the inbox.</p>
79
80
81<h2 id="Adding">Adding the Action Bar</h2>
82
83<p>The Action Bar is included by default in all activities that target Android 3.0 or greater. More
84specifically, all activities that use the new "holographic" theme include the Action Bar, and any
85application that targets Android 3.0 automatically receives this theme. An application is considered
86to "target" Android 3.0 when it has set either the {@code android:minSdkVersion} or {@code
87android:targetSdkVersion} attribute in the <a
88href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code &lt;uses-sdk&gt;}</a> element to
89{@code "11"} or greater. For example:</p>
90
91<pre>
92&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
93      package="com.example.helloworld"
94      android:versionCode="1"
95      android:versionName="1.0"&gt;
96    &lt;uses-sdk android:minSdkVersion="4"
97              <b>android:targetSdkVersion="11"</b> /&gt;
98    &lt;application ... &gt;
99        ...
100    &lt;/application&gt;
101&lt;/manifest&gt;
102</pre>
103
104<p>In this example, the application requires a minimum version of API
105Level 4 (Android 1.6), but it also targets API Level 11 (Android 3.0). This way, when
106the application is installed on a device running Android 3.0 or greater, the system applies the
107holographic theme to each activity, and thus, each activity includes the Action Bar.</p>
108
109<p>However, if you want to use Action Bar APIs, such as to add tabs or modify Action Bar styles,
110you need to set the {@code android:minSdkVersion} to {@code "11"}, so you can access the
111{@link android.app.ActionBar} class.</p>
112
113
114<h3 id="Removing">Removing the Action Bar</h3>
115
116<p>If you want to remove the Action Bar for a particular activity, set the activity theme to
117{@link android.R.style#Theme_Holo_NoActionBar Theme.Holo.NoActionBar}. For example:</p>
118
119<pre>
120&lt;activity android:theme="&#64;android:style/Theme.Holo.NoActionBar"&gt;
121</pre>
122
123<p class="note"><strong>Tip:</strong> If you have a custom activity theme in which you'd like to
124remove the Action Bar, set the {@link android.R.styleable#Theme_windowActionBar
125android:windowActionBar} style property {@code false}. See <a href="#Style">Styling the Action
126Bar</a> for more about Action Bar styles.</p>
127
128<p>You can also hide the Action Bar at runtime by calling {@link android.app.ActionBar#hide},
129then show it again by calling {@link android.app.ActionBar#show}. For example:</p>
130
131<pre>
132ActionBar actionBar = getActionBar();
133actionBar.hide();
134</pre>
135
136<p>When the Action Bar hides, the system adjusts your activity content to fill all the
137available screen space.</p>
138
139<p class="note"><strong>Note:</strong> If you remove the Action Bar using a theme, then the
140window will not allow the Action Bar at all, so you cannot add it at runtime&mdash;calling
141{@link android.app.Activity#getActionBar getActionBar()} will return null.</p>
142
143
144<h2 id="ActionItems">Adding Action Items</h2>
145
146<p>An action item is simply a menu item from the <a
147href="{@docRoot}guide/topics/ui/menus.html#OptionsMenu">Options Menu</a> which you declare should
148appear directly in the Action Bar. An action item can include an icon and/or text. If a menu
149item does not appear as an action item, then the system places it in the overflow menu, which
150the user can open with the menu icon on the right side of the Action Bar.</p>
151
152<div class="figure" style="width:359px">
153  <img src="{@docRoot}images/ui/actionbar-item-withtext.png" height="57" alt="" />
154  <p class="img-caption"><strong>Figure 2.</strong> A screenshot from an Action Bar with two
155action items and the overflow menu.</p>
156</div>
157
158<p>When the activity first starts, the system populates the Action Bar and overflow menu by calling
159{@link android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()} for your activity. As
160discussed in the <a href="{@docRoot}guide/topics/ui/menus.html">Menus</a> developer guid, it's in
161this callback method that you define the Options Menu for the activity.</p>
162
163<p>You can specify a menu item to appear as an action item&mdash;if there is room
164for it&mdash;from your <a href="{@docRoot}guide/topics/resources/menu-resource.html">menu
165resource</a> by declaring {@code
166android:showAsAction="ifRoom"} for the {@code &lt;item&gt;} element. This way, the menu item appears
167in the Action Bar for quick access only if there is room available for it. If there's not
168enough room, the item is placed the overflow menu (revealed by the menu icon on the right side
169of the Action Bar).</p>
170
171<p>You can also declare a menu item to appear as an action item from your application code, by
172calling {@link android.view.MenuItem#setShowAsAction setShowAsAction()} on the {@link
173android.view.MenuItem} and passing {@link android.view.MenuItem#SHOW_AS_ACTION_IF_ROOM}.</p>
174
175<p>If your menu item supplies both a title and an icon, then the action item shows only
176the icon by defult. If you want to include the text with the action item, add the "with
177text" flag: in XML, add {@code withText} to the {@code android:showAsAction} attribute or, in
178your application code, use the {@link android.view.MenuItem#SHOW_AS_ACTION_WITH_TEXT} flag when
179calling {@link android.view.MenuItem#setShowAsAction setShowAsAction()}. Figure 2 shows an Action
180Bar that has two action items with text and the icon for the overflow menu.</p>
181
182<p>Here's an example of how you can declare a menu item as an action item in a <a
183href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a> file:</p>
184<pre>
185&lt;?xml version="1.0" encoding="utf-8"?&gt;
186&lt;menu xmlns:android="http://schemas.android.com/apk/res/android">
187    &lt;item android:id="@+id/menu_save"
188          android:icon="@drawable/ic_menu_save"
189          android:title="@string/menu_save"
190          <b>android:showAsAction="ifRoom|withText"</b> /&gt;
191&lt;/menu&gt;
192</pre>
193
194<p>In this case, both the {@code ifRoom} and {@code withText} flags are set, so that when this
195item appears as an action item, it includes the title text along with the icon.</p>
196
197<p>A menu item placed in the Action Bar triggers the same callback methods as other items in the
198Options Menu. When the user selects an action item, your activity receives a call to
199{@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}, passing the
200item ID.</p>
201
202<p class="note"><strong>Note:</strong> If you added the menu item from a fragment, then the
203respective {@link
204android.app.Fragment#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} method is called
205for that fragment. However the activity gets a chance to handle it first, so the system calls {@link
206android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} on the activity
207before calling the fragment.</p>
208
209<p>You can also declare an item to <em>always</em> appear as an action item,  but you should avoid
210doing so, because it can create a cluttered UI if there are too many action items and they might
211collide with other elements in the Action Bar.</p>
212
213<p>For more information about menus, see the <a
214href="{@docRoot}guide/topics/ui/menus.html#options-menu">Menus</a> developer guide.</p>
215
216
217<h3 id="Home">Using the app icon as an action item</h3>
218
219<p>By default, your application icon appears in the Action Bar on the left side. It also responds
220to user interaction (when the user taps it, it visually responds the same way action
221items do) and it's your responsibility to do something when the user taps it.</p>
222
223<img src="{@docRoot}images/ui/actionbar.png" height="36" alt="" />
224<p class="img-caption"><strong>Figure 3.</strong> Email's Action Bar, with the
225application icon on the left.</p>
226
227<p>The normal behavior should be for your application to return to the "home" activity or the
228initial state (such as when the activity hasn't changed, but fragments have changed) when the user
229taps the icon. If the user is already at home or the initial state, then you don't need to do
230anything.</p>
231
232<p>When the user taps the icon, the system calls your activity's {@link
233android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} method with the  {@code
234android.R.id.home} ID. So, you need to add a condition to your {@link
235android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} method to listen for {@code
236android.R.id.home} and perform the appropriate action, such as start the home activity or pop recent
237fragment transactions off the stack.</p>
238
239<p>If you respond to the application icon by returning to the home activity, you should include
240the {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP} flag in the {@link
241android.content.Intent}. With this flag, if the activity you're starting already exists in the
242current task, then all activities on top of it are destroyed and it is brought to the front.
243You should favor this approach, because going "home" is an action that's equivalent to "going
244back" and you should usually not create a new instance of the home activity. Otherwise, you
245might end up with a long stack of activities in the current task.</p>
246
247<p>For example, here's an implementation of {@link android.app.Activity#onOptionsItemSelected
248onOptionsItemSelected()} that returns to the application's "home" activity:</p>
249
250<pre>
251&#64;Override
252public boolean onOptionsItemSelected(MenuItem item) {
253    switch (item.getItemId()) {
254        case android.R.id.home:
255            // app icon in Action Bar clicked; go home
256            Intent intent = new Intent(this, HomeActivity.class);
257            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
258            startActivity(intent);
259            return true;
260        default:
261            return super.onOptionsItemSelected(item);
262    }
263}
264</pre>
265
266
267
268
269<h4>Using the app icon to navigate "up"</h4>
270
271<div class="figure" style="width:144px">
272  <img src="{@docRoot}images/ui/actionbar-logo.png" height="140" alt="" />
273  <p class="img-caption"><strong>Figure 4.</strong> The standard icon for the Email application
274(top) and the "up" icon (bottom).</p>
275</div>
276
277<p>You can also use the application icon to provide "up" navigation for the user. This is especially
278useful when your application is composed of activities that generally appear in a certain order and
279you want to facilitate the ability for the user to navigate up the activity hierarchy
280(regardless of how they entered the current activity).</p>
281
282<p>The way you respond to this event is the same as when navigating home (as
283discussed above, except you start a different activity, based on the current activity). All you
284need to do to indicate to the user that the behavior is different is set the Action Bar to "show
285home as up." You can do so by calling {@link android.app.ActionBar#setDisplayHomeAsUpEnabled
286setDisplayHomeAsUpEnabled(true)} on your activity's {@link android.app.ActionBar}. When you do, the
287system draws your application icon with an arrow indicating the up behavior, as shown in figure
2884.</p>
289
290<p>For example, here's how you can show the application icon as an "up" action:</p>
291
292<pre>
293&#64;Override
294protected void onStart() {
295    super.onStart();
296    ActionBar actionBar = this.getActionBar();
297    actionBar.setDisplayHomeAsUpEnabled(true);
298}
299</pre>
300
301<p>Then, your activity should respond to the user tapping the icon, from the {@link
302android.app.Activity#onOptionsItemSelected
303onOptionsItemSelected()}, by listening for the {@code android.R.id.home} ID (as shown above). In
304this case, when navigating up, it's even more important that you use the {@link
305android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP} flag in the {@link android.content.Intent}, so that
306you don't create a new instance of the parent activity if one already exists.</p>
307
308
309
310
311<h2 id="ActionView">Adding an Action View</h2>
312
313<div class="figure" style="width:429px">
314  <img src="{@docRoot}images/ui/actionbar-actionview.png" alt="" />
315  <p class="img-caption"><strong>Figure 5.</strong> An action view with a {@link
316android.widget.SearchView} widget.</p>
317</div>
318
319<p>An action view is a widget that appears in the Action Bar as a substitute for an action
320item. For example, if you have an item in the Options Menu for "Search", you can add an action view
321for the item that provides a {@link android.widget.SearchView} widget in the Action Bar whenever
322the item is enabled as an action item.</p>
323
324<p>When adding an action view for a menu item, it's important that you still allow the item to
325behave as a normal menu item when it does not appear in the Action Bar. For example, a menu item to
326perform a search should, by default, bring up the Android search dialog, but if the item is
327placed in the Action Bar, the action view appears with a {@link android.widget.SearchView}
328widget. Figure 4 shows an example of  the {@link android.widget.SearchView} widget in an action
329view.</p>
330
331<p>The best way to declare an action view for an item is in your <a
332href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a>, using the {@code
333android:actionLayout} or {@code android:actionViewClass} attribute:</p>
334
335<ul>
336  <li>The value for {@code android:actionLayout} must be a resource pointer to a layout file.
337For example:
338<pre>
339&lt;?xml version="1.0" encoding="utf-8"?>
340&lt;menu xmlns:android="http://schemas.android.com/apk/res/android">
341    &lt;item android:id="@+id/menu_search"
342        android:title="Search"
343        android:icon="@drawable/ic_menu_search"
344        android:showAsAction="ifRoom"
345        <b>android:actionLayout="@layout/searchview"</b> /&gt;
346&lt;/menu>
347</pre>
348</li>
349
350  <li>The value for {@code android:actionViewClass} must be a fully-qualified class name for
351the {@link android.view.View} you want to use. For example:
352<pre>
353&lt;?xml version="1.0" encoding="utf-8"?>
354&lt;menu xmlns:android="http://schemas.android.com/apk/res/android">
355    &lt;item android:id="@+id/menu_search"
356        android:title="Search"
357        android:icon="@drawable/ic_menu_search"
358        android:showAsAction="ifRoom"
359        <b>android:actionViewClass="android.widget.SearchView"</b> /&gt;
360&lt;/menu>
361</pre></li>
362</ul>
363
364<p class="note">You must include {@code android:showAsAction="ifRoom"} in order for the item to
365appear as an action view when room is available. If necessary, however, you can force the item to
366always appear as an action view by setting {@code android:showAsAction} to {@code "always"}.</p>
367
368<p>Now, when the menu item is displayed as an action item, it's action view appears instead of
369the icon and/or title text. However, if there's not enough room in the Action Bar, the item appears
370in the overflow menu as a normal menu item and you must respond to it from the {@link
371android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} callback method.</p>
372
373<p>When the activity first starts, the system populates the Action Bar and overflow menu by calling
374{@link android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()}.
375After you've inflated your menu in this method, you can acquire elements in an action view
376(perhaps in order to attach listeners) by calling {@link android.view.Menu#findItem
377findItem()} with the ID of the menu item, then {@link android.view.MenuItem#getActionView} on
378the returned {@link android.view.MenuItem}. For example, the search widget from the above samples is
379acquired like this:</p>
380
381<pre>
382&#64;Override
383public boolean onCreateOptionsMenu(Menu menu) {
384  getMenuInflater().inflate(R.menu.options, menu);
385  SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
386  // Set appropriate listeners for searchView
387  ...
388  return super.onCreateOptionsMenu(menu);
389}
390</pre>
391
392<p>For more information about using the search widget, see <a
393href="{@docRoot}guide/topics/search/search-dialog.html">Creating a Search Interface</a>.</p>
394
395
396
397
398<h2 id="Tabs">Adding Tabs</h2>
399
400
401<div class="figure" style="width:504px">
402  <img src="{@docRoot}images/ui/actionbar-tabs.png" alt="" />
403  <p class="img-caption"><strong>Figure 6.</strong> Screenshot of tabs in the
404Action Bar, from the <a
405href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery</a> sample
406application.</p>
407</div>
408
409<p>The Action Bar can display tabs that allow the user navigate between different fragments in the
410activity. Each tab can include a title and/or an icon.</p>
411
412<p>To begin, your layout must include a {@link android.view.View} in which each {@link
413android.app.Fragment} associated with a tab is displayed. Be sure the view has an ID that you
414can use to reference it from your code.</p>
415
416<p>To add tabs to the Action Bar:</p>
417<ol>
418  <li>Create an implementation of {@link android.app.ActionBar.TabListener} to handle the
419interaction events on the Action Bar tabs. You must implement all methods: {@link
420android.app.ActionBar.TabListener#onTabSelected onTabSelected()}, {@link
421android.app.ActionBar.TabListener#onTabUnselected onTabUnselected()}, and {@link
422android.app.ActionBar.TabListener#onTabReselected onTabReselected()}.
423    <p>Each callback method passes the {@link android.app.ActionBar.Tab} that received the
424event and a {@link android.app.FragmentTransaction} for you to perform the fragment
425transactions (add or remove fragments).</p>
426    <p>For example:</p>
427<pre>
428private class MyTabListener implements ActionBar.TabListener {
429    private TabContentFragment mFragment;
430
431    // Called to create an instance of the listener when adding a new tab
432    public MyTabListener(TabContentFragment fragment) {
433        mFragment = fragment;
434    }
435
436    public void onTabSelected(Tab tab, FragmentTransaction ft) {
437        ft.add(R.id.fragment_content, mFragment, null);
438    }
439
440    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
441        ft.remove(mFragment);
442    }
443
444    public void onTabReselected(Tab tab, FragmentTransaction ft) {
445        // do nothing
446    }
447
448}
449</pre>
450  <p>This implementation of {@link android.app.ActionBar.TabListener} adds a constructor
451that saves the {@link android.app.Fragment} associated with a tab so that each callback
452can add or remove that fragment.</p>
453  </li>
454  <li>Get the {@link android.app.ActionBar} for your activity by calling {@link
455android.app.Activity#getActionBar} from your {@link android.app.Activity}, during {@link
456android.app.Activity#onCreate onCreate()} (but be sure you do so <em>after</em> you've called
457{@link android.app.Activity#setContentView setContentView()}).</li>
458  <li>Call {@link android.app.ActionBar#setNavigationMode(int)
459setNavigationMode(NAVIGATION_MODE_TABS)} to enable tab mode for the {@link
460android.app.ActionBar}.</li>
461  <li>Create each tab for the Action Bar:
462    <ol>
463      <li>Create a new {@link android.app.ActionBar.Tab} by calling {@link
464android.app.ActionBar#newTab()} on the {@link android.app.ActionBar}.</li>
465      <li>Add title text and/or an icon for the tab by calling {@link
466android.app.ActionBar.Tab#setText setText()} and/or {@link android.app.ActionBar.Tab#setIcon
467setIcon()}.
468        <p class="note"><strong>Tip:</strong> These methods return the same {@link
469android.app.ActionBar.Tab} instance, so you can chain the calls together.</p></li>
470      <li>Declare the {@link android.app.ActionBar.TabListener} to use for the tab by passing an
471instance of your implementation to {@link android.app.ActionBar.Tab#setTabListener
472setTabListener()}.
473    </ol>
474  </li>
475  <li>Add each {@link android.app.ActionBar.Tab} to the Action Bar by calling {@link
476android.app.ActionBar#addTab addTab()} on the {@link android.app.ActionBar} and passing the
477{@link android.app.ActionBar.Tab}.</li>
478</ol>
479<p>For example, the following code combines steps 2 - 5 to create two tabs and add them to
480the Action Bar:</p>
481<pre>
482&#64;Override
483protected void onCreate(Bundle savedInstanceState) {
484    super.onCreate(savedInstanceState);
485    setContentView(R.layout.main);
486
487    // setup Action Bar for tabs
488    final ActionBar actionBar = getActionBar();
489    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
490    // remove the activity title to make space for tabs
491    actionBar.setDisplayShowTitleEnabled(false);
492
493    // instantiate fragment for the tab
494    Fragment artistsFragment = new ArtistsFragment();
495    // add a new tab and set its title text and tab listener
496    actionBar.addTab(actionBar.newTab().setText(R.string.tab_artists)
497            .setTabListener(new TabListener(artistsFragment)));
498
499    Fragment albumsFragment = new AlbumsFragment();
500    actionBar.addTab(actionBar.newTab().setText(R.string.tab_albums)
501            .setTabListener(new TabListener(albumsFragment)));
502}
503</pre>
504
505<p>All the behaviors that occur when a tab is selected must be defined by your {@link
506android.app.ActionBar.TabListener} callback methods. When a tab is selected, it receives a call to
507{@link android.app.ActionBar.TabListener#onTabSelected onTabSelected()} and that's where you should
508add the appropriate fragment to the designated view in your layout, using {@link
509android.app.FragmentTransaction#add add()} with the provided {@link
510android.app.FragmentTransaction}. Likewise, when a tab is deselected (because another tab becomes
511selected), you should remove that fragment from the layout, using {@link
512android.app.FragmentTransaction#remove remove()}.</p>
513
514<p class="caution"><strong>Caution:</strong> You <strong>must not</strong> call {@link
515android.app.FragmentTransaction#commit} for these transactions&mdash;the system calls it for you
516and it may throw an exception if you call it yourself. You also <strong>cannot</strong> add these
517fragment transactions to the back stack.</p>
518
519<p>If your activity is stopped, you should retain the currently selected tab with the saved state so
520that when the user returns to your application, you can open the tab. When it's time to save the
521state, you can query the currently selected tab with {@link
522android.app.ActionBar#getSelectedNavigationIndex()}. This returns the index position of the selected
523tab.</p>
524
525<p class="caution"><strong>Caution:</strong> It's important that you save
526the state of each fragment as necessary, so when the user switches fragments with the tabs,
527then returns to a previous fragment, it appears the way they left. For information about saving
528the state of your fragment, see the <a
529href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> developer guide.</p>
530
531
532
533
534<h2 id="Dropdown">Adding Drop-down Navigation</h2>
535
536<p>As another mode of navigation within your activity, you can provide a drop-down list in the
537Action Bar. For example, the drop-down list can provide alternative modes for sorting the content in
538the activity or switching the user's account.</p>
539
540<!--
541<div class="figure" style="width:135px">
542  <img src="{@docRoot}images/ui/actionbar-dropdown.png" alt="" />
543  <p class="img-caption"><strong>Figure 5.</strong> Screenshot of a drop-down navigation list in the
544Action Bar.</p>
545</div>
546-->
547
548<p>Here's a quick list of steps to enable drop-down navigation:</p>
549
550<ol>
551  <li>Create a {@link android.widget.SpinnerAdapter} that provides the
552list of selectable items for the drop-down and the layout to use when drawing each item in the
553list.</li>
554  <li>Implement {@link android.app.ActionBar.OnNavigationListener} to define the behavior when the
555user selects an item from the list.</li>
556  <li>Enable navigation mode for the Action Bar with {@link
557android.app.ActionBar#setNavigationMode setNavigationMode()}. For example:
558<pre>
559ActionBar actionBar = getActionBar();
560actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
561</pre>
562  <p class="note"><strong>Note:</strong> You should perform this during your activity's {@link
563android.app.Activity#onCreate
564onCreate()} method.</p>
565  </li>
566  <li>Then, set the callback for the drop-down list with {@link
567android.app.ActionBar#setListNavigationCallbacks setListNavigationCallbacks()}. For example:
568<pre>
569actionBar.setListNavigationCallbacks(mSpinnerAdapter, mNavigationCallback);
570</pre>
571<p>This method takes your {@link android.widget.SpinnerAdapter} and {@link
572android.app.ActionBar.OnNavigationListener}. More about these next.</p>
573</li>
574</ol>
575
576<p>That's the basic setup. However, implementing the {@link android.widget.SpinnerAdapter} and
577{@link android.app.ActionBar.OnNavigationListener} is where most of the work is done. There are many
578ways you can implement these to define the functionality for your drop-down navigation and
579implementing various types of {@link android.widget.SpinnerAdapter} is beyond the scope of this
580document (you should refer to the {@link android.widget.SpinnerAdapter} class reference for more
581information). However, below is a simple example for a {@link android.widget.SpinnerAdapter} and
582{@link android.app.ActionBar.OnNavigationListener} to get you started (click the title to
583reveal the sample).</p>
584
585
586
587<div class="toggle-content closed">
588
589  <h3 id="Spinner"><a href="#" onclick="return toggleContent(this)">
590    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img" alt="" />
591    Example SpinnerAdapter and OnNavigationListener
592  </a></h3>
593
594  <div class="toggle-content-toggleme">
595
596<p>{@link android.widget.SpinnerAdapter} is an adapter that provides data for a spinner widget,
597such as the drop-down list in the Action Bar. {@link android.widget.SpinnerAdapter} is an interface
598that you can implement, but Android includes some useful implementations that you can extend, such
599as {@link android.widget.ArrayAdapter} and {@link
600android.widget.SimpleCursorAdapter}. For example, here's an easy way to create a {@link
601android.widget.SpinnerAdapter} by using {@link android.widget.ArrayAdapter} implementation, which
602uses a string array as the data source:</p>
603
604<pre>
605SpinnerAdapter mSpinnerAdapter = ArrayAdapter.createFromResource(this, R.array.action_list,
606          android.R.layout.simple_spinner_dropdown_item);
607</pre>
608
609<p>The {@link android.widget.ArrayAdapter#createFromResource createFromResource()} method takes
610three parameters: the application {@link android.content.Context}, the resource ID for the string
611array, and the layout to use for each list item.</p>
612
613<p>A <a href="{@docRoot}guide/topics/resources/string-resource.html#StringArray">string array</a>
614defined in a resource looks like this:</p>
615
616<pre>
617&lt;?xml version="1.0" encoding="utf-8"?&gt;
618&lt;resources&gt;
619    &lt;string-array name="action_list"&gt;
620        &lt;item&gt;Mercury&lt;/item&gt;
621        &lt;item&gt;Venus&lt;/item&gt;
622        &lt;item&gt;Earth&lt;/item&gt;
623    &lt;/string-array&gt;
624&lt;/pre&gt;
625</pre>
626
627<p>The {@link android.widget.ArrayAdapter} returned by {@link
628android.widget.ArrayAdapter#createFromResource createFromResource()} is complete and ready for you
629to pass it to {@link android.app.ActionBar#setListNavigationCallbacks setListNavigationCallbacks()}
630(in step 4 from above). Before you do, though, you need to create the {@link
631android.app.ActionBar.OnNavigationListener OnNavigationListener}.</p>
632
633
634<p>Your implementation of {@link android.app.ActionBar.OnNavigationListener} is where you handle
635fragment changes or other modifications to your activity when the user selects an item from the
636drop-down list. There's only one callback method to implement in the listener: {@link
637android.app.ActionBar.OnNavigationListener#onNavigationItemSelected onNavigationItemSelected()}.</p>
638
639<p>The {@link
640android.app.ActionBar.OnNavigationListener#onNavigationItemSelected onNavigationItemSelected()}
641method receives the position of the item in the list and a unique item ID provided by the {@link
642android.widget.SpinnerAdapter}.</p>
643
644<p>Here's an example that instantiates an anonymous implementation of {@link
645android.app.ActionBar.OnNavigationListener OnNavigationListener}, which inserts a {@link
646android.app.Fragment} into the
647layout container identified by {@code R.id.fragment_container}:</p>
648
649<pre>
650mOnNavigationListener = new OnNavigationListener() {
651  // Get the same strings provided for the drop-down's ArrayAdapter
652  String[] strings = getResources().getStringArray(R.array.action_list);
653
654  &#64;Override
655  public boolean onNavigationItemSelected(int position, long itemId) {
656    // Create new fragment from our own Fragment class
657    ListContentFragment newFragment = new ListContentFragment();
658    FragmentTransaction ft = openFragmentTransaction();
659    // Replace whatever is in the fragment container with this fragment
660    //  and give the fragment a tag name equal to the string at the position selected
661    ft.replace(R.id.fragment_container, newFragment, strings[position]);
662    // Apply changes
663    ft.commit();
664    return true;
665  }
666};
667</pre>
668
669<p>This instance of {@link android.app.ActionBar.OnNavigationListener OnNavigationListener} is
670complete and you can now call {@link android.app.ActionBar#setListNavigationCallbacks
671setListNavigationCallbacks()} (in step 4), passing the {@link android.widget.ArrayAdapter} and this
672{@link android.app.ActionBar.OnNavigationListener OnNavigationListener}.</p>
673
674<p>In this example, when the user selects an item from the drop-down list, a fragment is added to
675the layout (replacing the current fragment in the {@code R.id.fragment_container} view). The
676fragment added is given a tag that uniquely identifies it, which is the same string used to
677identify the fragment in the drop-down list.</p>
678
679<p>Here's a look at the {@code ListContentFragment} class that defines each fragment in this
680example:</p>
681
682<pre>
683public class ListContentFragment extends Fragment {
684    private String mText;
685
686    &#64;Override
687    public void onAttach(Activity activity) {
688      // This is the first callback received; here we can set the text for
689      // the fragment as defined by the tag specified during the fragment transaction
690      super.onAttach(activity);
691      mText = getTag();
692    }
693
694    &#64;Override
695    public View onCreateView(LayoutInflater inflater, ViewGroup container,
696            Bundle savedInstanceState) {
697        // This is called to define the layout for the fragment;
698        // we just create a TextView and set its text to be the fragment tag
699        TextView text = new TextView(getActivity());
700        text.setText(mText);
701        return text;
702    }
703}
704</pre>
705
706  </div><!-- end toggle-content-toggleme -->
707
708</div><!-- end toggle-content -->
709
710
711
712
713
714<h2 id="Style">Styling the Action Bar</h2>
715
716<p>The Action Bar is the heading for your application and a primary interaction point for users,
717so you might want to modify some of its design in order to make it feel more integrated with your
718application design. There are several ways you can do this if you wish.</p>
719
720<p>For simple modifications to the {@link android.app.ActionBar}, you can use the following
721methods:</p>
722
723<dl>
724  <dt>{@link android.app.ActionBar#setBackgroundDrawable setBackgroundDrawable()}</dt>
725  <dd>Sets a drawable to use as the Action Bar's background. The drawable should be a <a
726href="{@docRoot}guide/topics/graphics/2d-graphics.html#nine-patch">Nine-patch</a> image, a <a
727href="{@docRoot}guide/topics/resources/drawable-resource.html#Shape">shape</a>, or a <a
728href="{@docRoot}guide/topics/resources/more-resources.html#Color">solid color</a>, so the system can
729resize the drawable based on the size of the Action Bar (you should <em>not</em> use a fixed-size
730bitmap image).</dd>
731
732  <dt>{@link android.app.ActionBar#setDisplayUseLogoEnabled setDisplayUseLogoEnabled()}</dt>
733  <dd>Enables the use of an alternative image (a "logo") in the Action Bar, instead of the default
734application icon. A logo is often a wider, more detailed image that represents the application.
735When this is enabled, the system uses the logo image defined for the application (or the
736individual activity) in the manifest file, with the <a
737href="{@docRoot}guide/topics/manifest/application-element.html#logo">{@code android:logo}</a>
738attribute. The logo will be resized as necessary to fit the height of the Action Bar. (Best
739practice is to design the logo at the same size as your application icon.)</dd>
740</dl>
741
742
743<p>For more complex customizations, you can use Android's <a
744href="{@docRoot}guide/topics/ui/themes.html">style and theme</a> framework to restyle your Action
745Bar in several ways.</p>
746
747<p>The Action Bar has two standard themes, "dark" and "light". The dark theme is applied with
748the default holographic theme, as specified by the {@link android.R.style#Theme_Holo Theme.Holo}
749theme. If you want a white background with dark text, instead, you can apply the {@link
750android.R.style#Theme_Holo_Light Theme.Holo.Light} theme to the activity in the manifest file. For
751example:</p>
752
753<pre>
754&lt;activity android:name=".ExampleActivity"
755          android:theme="@android:style/Theme.Holo.Light" />
756</pre>
757
758<p>For more control, you can override either the {@link android.R.style#Theme_Holo
759Theme.Holo} or {@link android.R.style#Theme_Holo_Light Theme.Holo.Light} theme and apply custom
760styles to certain aspects of the Action Bar. Some of the Action Bar properties you can customize
761include the following:</p>
762
763<dl>
764  <dt>{@link android.R.styleable#Theme_actionBarTabStyle
765      android:actionBarTabStyle}</dt>
766  <dd>Style for tabs in the Action Bar.</dd>
767
768  <dt>{@link android.R.styleable#Theme_actionBarTabBarStyle
769      android:actionBarTabBarStyle}</dt>
770  <dd>Style for the bar that appears below tabs in the Action Bar.</dd>
771
772  <dt>{@link android.R.styleable#Theme_actionBarTabTextStyle
773      android:actionBarTabTextStyle}</dt>
774  <dd>Style for the text in the tabs.</dd>
775
776  <dt>{@link android.R.styleable#Theme_actionDropDownStyle
777      android:actionDropDownStyle}</dt>
778  <dd>Style for the drop-down list used for the overflow menu and drop-down navigation.</dd>
779
780  <dt>{@link android.R.styleable#Theme_actionButtonStyle
781      android:actionButtonStyle}</dt>
782  <dd>Style for the background image used for buttons in the Action Bar.</dd>
783
784</dl>
785
786<p>For example, here's a resource file that defines a custom theme for the Action Bar, based on
787the standard {@link android.R.style#Theme_Holo Theme.Holo} theme:</p>
788
789<pre>
790&lt;?xml version="1.0" encoding="utf-8"?>
791&lt;resources>
792    &lt;!-- the theme applied to the application or activity -->
793    &lt;style name="CustomActionBar" parent="android:style/Theme.Holo.Light">
794        &lt;item name="android:actionBarTabTextStyle">@style/customActionBarTabTextStyle&lt;/item>
795        &lt;item name="android:actionBarTabStyle">@style/customActionBarTabStyle&lt;/item>
796        &lt;item name="android:actionBarTabBarStyle">@style/customActionBarTabBarStyle&lt;/item>
797    &lt;/style>
798
799    &lt;!-- style for the tab text -->
800    &lt;style name="customActionBarTabTextStyle">
801        &lt;item name="android:textColor">#2966c2&lt;/item>
802        &lt;item name="android:textSize">20sp&lt;/item>
803        &lt;item name="android:typeface">sans&lt;/item>
804    &lt;/style>
805
806    &lt;!-- style for the tabs -->
807    &lt;style name="customActionBarTabStyle">
808        &lt;item name="android:background">@drawable/actionbar_tab_bg&lt;/item>
809        &lt;item name="android:paddingLeft">20dp&lt;/item>
810        &lt;item name="android:paddingRight">20dp&lt;/item>
811    &lt;/style>
812
813    &lt;!-- style for the tab bar -->
814    &lt;style name="customActionBarTabBarStyle">
815        &lt;item name="android:background">@drawable/actionbar_tab_bar&lt;/item>
816    &lt;/style>
817&lt;/resources>
818</pre>
819
820<p class="note"><strong>Note:</strong> In order for the tab background image to change,
821depending on the current tab state (selected, pressed, unselected), the drawable resource used
822must be a <a href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList">state
823list drawable</a>. Also be certain that your theme declares a parent theme, from which it
824inherits all styles not explicitly declared in your theme.</p>
825
826<p>You can apply your custom theme to the entire application or to individual activities in your
827manifest file, like this:</p>
828
829<pre>
830&lt;application android:theme="&#64;style/CustomActionBar"
831             ... />
832</pre>
833
834<p>Additionally, if you want to create a custom theme for your activity that removes the Action
835Bar completely, use the following style attributes:</p>
836
837<dl>
838  <dt>{@link android.R.styleable#Theme_windowActionBar
839      android:windowActionBar}</dt>
840  <dd>Set this style property {@code false} to remove the Action Bar.</dd>
841
842  <dt>{@link android.R.styleable#Theme_windowNoTitle
843      android:windowNoTitle}</dt>
844  <dd>Set this style property {@code true} to also remove the traditional title bar.</dd>
845</dl>
846
847<p>For more information about using themes in your application, read <a
848href="{@docRoot}guide/topics/ui/themes.html">Styles and Themes</a>.</p>
849
850
851
852
853