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—but reside in a different package namespace—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><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<application>}</a> or <a 188href="{@docRoot}guide/topics/manifest/activity-element.html">{@code 189<activity>}</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—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<menu xmlns:android="http://schemas.android.com/apk/res/android" > 227 <item android:id="@+id/action_search" 228 android:icon="@drawable/ic_action_search" 229 android:title="@string/action_search"/> 230 <item android:id="@+id/action_compose" 231 android:icon="@drawable/ic_action_compose" 232 android:title="@string/action_compose" /> 233</menu> 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@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 <item>} tag. For example:</p> 253 254<pre> 255<menu xmlns:android="http://schemas.android.com/apk/res/android" 256 <strong>xmlns:yourapp="http://schemas.android.com/apk/res-auto"</strong> > 257 <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> /> 261 ... 262</menu> 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 <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—with the {@code title} and 279{@code icon} attributes—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<item yourapp:showAsAction="ifRoom|withText" ... /> 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 <item>} 323tag's {@code id} attribute so you can perform the appropriate action. For example:</p> 324 325<pre> 326@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 <activity>}</a> 377element or to the 378<a href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</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 <meta-data>}</a> 383 element as a child of each 384 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</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<manifest ...> 392 <activity uiOptions="splitActionBarWhenNarrow" ... > 393 <meta-data android:name="android.support.UI_OPTIONS" 394 android:value="splitActionBarWhenNarrow" /> 395 </activity> 396</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@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<activity>}</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<meta-data>}</a> element that specifies 467the parent activity as the value for {@code android.support.PARENT_ACTIVITY}. For example:</p> 468<pre> 469<application ... > 470 ... 471 <!-- The main/home activity (has no parent activity) --> 472 <activity 473 android:name="com.example.myfirstapp.MainActivity" ...> 474 ... 475 </activity> 476 <!-- A child of the main activity --> 477 <activity 478 android:name="com.example.myfirstapp.DisplayMessageActivity" 479 android:label="@string/title_activity_display_message" 480 android:parentActivityName="com.example.myfirstapp.MainActivity" > 481 <!-- Parent activity meta-data to support API level 7+ --> 482 <meta-data 483 android:name="android.support.PARENT_ACTIVITY" 484 android:value="com.example.myfirstapp.MainActivity" /> 485 </activity> 486</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—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<?xml version="1.0" encoding="utf-8"?> 569<menu xmlns:android="http://schemas.android.com/apk/res/android" 570 xmlns:yourapp="http://schemas.android.com/apk/res-auto" > 571 <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> /> 576</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@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@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 @Override 653 public boolean onMenuItemActionCollapse(MenuItem item) { 654 // Do something when collapsed 655 return true; // Return true to collapse action view 656 } 657 658 @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 <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 <item>} tag with 713the {@link android.support.v7.widget.ShareActionProvider} class. For example:</p> 714 715<pre> 716<?xml version="1.0" encoding="utf-8"?> 717<menu xmlns:android="http://schemas.android.com/apk/res/android" 718 xmlns:yourapp="http://schemas.android.com/apk/res-auto" > 719 <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 /> 724 ... 725</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@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 @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<T extends Fragment> implements ActionBar.TabListener { 943 private Fragment mFragment; 944 private final Activity mActivity; 945 private final String mTag; 946 private final Class<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<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—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—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)—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@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<ArtistFragment>( 1019 this, "artist", ArtistFragment.class)); 1020 actionBar.addTab(tab); 1021 1022 tab = actionBar.newTab() 1023 .setText(R.string.album) 1024 .setTabListener(new TabListener<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<?xml version="1.0" encoding="utf-8"?> 1142<resources> 1143 <string-array name="action_list"> 1144 <item>Mercury</item> 1145 <item>Venus</item> 1146 <item>Earth</item> 1147 </string-array> 1148</pre> 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 @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 @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 @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<SomeView 1324 ... 1325 android:layout_marginTop="?android:attr/actionBarSize" /> 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<?xml version="1.0" encoding="utf-8"?> 1434<resources> 1435 <!-- the theme applied to the application or activity --> 1436 <style name="CustomActionBarTheme" 1437 parent="@style/Theme.AppCompat.Light"> 1438 <item name="android:actionBarStyle">@style/MyActionBar</item> 1439 <item name="android:actionBarTabTextStyle">@style/TabTextStyle</item> 1440 <item name="android:actionMenuTextColor">@color/actionbar_text</item> 1441 1442 <!-- Support library compatibility --> 1443 <item name="actionBarStyle">@style/MyActionBar</item> 1444 <item name="actionBarTabTextStyle">@style/TabTextStyle</item> 1445 <item name="actionMenuTextColor">@color/actionbar_text</item> 1446 </style> 1447 1448 <!-- general styles for the action bar --> 1449 <style name="MyActionBar" 1450 parent="@style/Widget.AppCompat.ActionBar"> 1451 <item name="android:titleTextStyle">@style/TitleTextStyle</item> 1452 <item name="android:background">@drawable/actionbar_background</item> 1453 <item name="android:backgroundStacked">@drawable/actionbar_background</item> 1454 <item name="android:backgroundSplit">@drawable/actionbar_background</item> 1455 1456 <!-- Support library compatibility --> 1457 <item name="titleTextStyle">@style/TitleTextStyle</item> 1458 <item name="background">@drawable/actionbar_background</item> 1459 <item name="backgroundStacked">@drawable/actionbar_background</item> 1460 <item name="backgroundSplit">@drawable/actionbar_background</item> 1461 </style> 1462 1463 <!-- action bar title text --> 1464 <style name="TitleTextStyle" 1465 parent="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"> 1466 <item name="android:textColor">@color/actionbar_text</item> 1467 </style> 1468 1469 <!-- action bar tab text --> 1470 <style name="TabTextStyle" 1471 parent="@style/Widget.AppCompat.ActionBar.TabText"> 1472 <item name="android:textColor">@color/actionbar_text</item> 1473 </style> 1474</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<application android:theme="@style/CustomActionBarTheme" ... /> 1482</pre> 1483 1484<p>Or to individual activities:</p> 1485 1486<pre> 1487<activity android:theme="@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 <style>} 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