blob: a12244379969539b269fcfcb5c76fad1805b2f12 [file] [log] [blame]
Scott Mainb10b48f2011-09-13 16:40:52 -07001page.title=Action Bar
Joe Fernandez33baa5a2013-11-14 11:41:19 -08002page.tags=actionbar,menu,tabs
Scott Mainf2134152013-07-23 19:18:40 -07003
Scott Main18439be2010-09-07 17:11:38 -07004@jd:body
5
Scott Maine04c4542013-06-18 21:16:25 -07006
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
Scott Main18439be2010-09-07 17:11:38 -070014<div id="qv-wrapper">
15<div id="qv">
16
Scott Main18439be2010-09-07 17:11:38 -070017 <h2>In this document</h2>
Scott Main258a51e2011-10-25 12:11:40 -070018<ol>
19 <li><a href="#Adding">Adding the Action Bar</a>
20 <ol>
21 <li><a href="#Removing">Removing the action bar</a></li>
Scott Maine04c4542013-06-18 21:16:25 -070022 <li><a href="#Logo">Using a logo instead of an icon</a></li>
Scott Main258a51e2011-10-25 12:11:40 -070023 </ol>
24 </li>
25 <li><a href="#ActionItems">Adding Action Items</a>
26 <ol>
Scott Maine04c4542013-06-18 21:16:25 -070027 <li><a href="#ActionEvents">Handling clicks on action items</a></li>
Scott Main258a51e2011-10-25 12:11:40 -070028 <li><a href="#SplitBar">Using split action bar</a></li>
29 </ol>
30 </li>
Scott Maine04c4542013-06-18 21:16:25 -070031 <li><a href="#Home">Navigating Up with the App Icon</a></li>
Scott Main258a51e2011-10-25 12:11:40 -070032 <li><a href="#ActionView">Adding an Action View</a>
33 <ol>
34 <li><a href="#ActionViewCollapsing">Handling collapsible action views</a></li>
Scott Maine04c4542013-06-18 21:16:25 -070035 </ol>
Scott Main258a51e2011-10-25 12:11:40 -070036 </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>
Scott Maine04c4542013-06-18 21:16:25 -070051 <li><a href="#StyleExample">Example theme</a></li>
Scott Main258a51e2011-10-25 12:11:40 -070052 </ol>
53 </li>
54</ol>
Scott Main18439be2010-09-07 17:11:38 -070055
56 <h2>Key classes</h2>
57 <ol>
Scott Maine04c4542013-06-18 21:16:25 -070058 <li>{@link android.support.v7.app.ActionBar}</li>
Scott Main18439be2010-09-07 17:11:38 -070059 <li>{@link android.view.Menu}</li>
60 </ol>
Scott Main258a51e2011-10-25 12:11:40 -070061
Scott Main18439be2010-09-07 17:11:38 -070062</div>
63</div>
64
Scott Maine04c4542013-06-18 21:16:25 -070065<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>
Scott Main258a51e2011-10-25 12:11:40 -070069
Scott Maine04c4542013-06-18 21:16:25 -070070<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>
Scott Main18439be2010-09-07 17:11:38 -070075
76<ul>
Scott Maine04c4542013-06-18 21:16:25 -070077 <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>
Scott Main18439be2010-09-07 17:11:38 -070083</ul>
84
Scott Maine04c4542013-06-18 21:16:25 -070085<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>
Scott Main6ea0d2c2011-01-27 16:03:25 -080088
Scott Maine04c4542013-06-18 21:16:25 -070089<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>
Scott Mainf2134152013-07-23 19:18:40 -070091for compatibility with Android 2.1 (API level 7) and above.</p>
Scott Maine04c4542013-06-18 21:16:25 -070092
93<p><b>This guide focuses on how to use the
94support library's action bar</b>, but if your app supports <em>only</em> Android 3.0 or higher, you
95should use the {@link android.app.ActionBar} APIs in the framework. Most of the APIs are
96the same&mdash;but reside in a different package namespace&mdash;with a few exceptions to method
97names or signatures that are noted in the sections below.</p>
98
99
100<div class="caution">
101<p><strong>Caution:</strong> Be certain you import
102the {@code ActionBar} class (and related APIs) from the appropriate package:</p>
103<ul>
104<li>If supporting API levels <em>lower than</em> 11: <br>
105{@code import android.support.v7.app.ActionBar}</li>
106<li>If supporting <em>only</em> API level 11 and higher: <br>
107{@code import android.app.ActionBar}</li>
108</ul>
109</div>
110
111
112<p class="note"><strong>Note:</strong> If you're looking for information about the <em>contextual
113action bar</em> for displaying contextual action items, see the <a
Scott Main5e095932011-12-16 13:06:22 -0800114href="{@docRoot}guide/topics/ui/menus.html#context-menu">Menu</a> guide.</p>
115
Scott Main258a51e2011-10-25 12:11:40 -0700116
Scott Main18439be2010-09-07 17:11:38 -0700117
118<h2 id="Adding">Adding the Action Bar</h2>
119
Scott Maine04c4542013-06-18 21:16:25 -0700120<p>As mentioned above, this guide focuses on how to use the {@link
121android.support.v7.app.ActionBar} APIs in the support library. So before you can add the action
122bar, you must set up your project with the <strong>appcompat v7</strong> support library by
123following the instructions in the <a href="{@docRoot}tools/support-library/setup.html">Support
124Library Setup</a>.</p>
125
126<p>Once your project is set up with the support library, here's how to add the action bar:</p>
127<ol>
128 <li>Create your activity by extending {@link android.support.v7.app.ActionBarActivity}.</li>
129 <li>Use (or extend) one of the {@link android.support.v7.appcompat.R.style#Theme_AppCompat
130 Theme.AppCompat} themes for your activity. For example:
131 <pre>&lt;activity android:theme="@style/Theme.AppCompat.Light" ... ></pre>
132 </li>
133</ol>
134
Scott Mainf2134152013-07-23 19:18:40 -0700135<p>Now your activity includes the action bar when running on Android 2.1 (API level 7) or higher.
Scott Maine04c4542013-06-18 21:16:25 -0700136</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
Scott Main258a51e2011-10-25 12:11:40 -0700142descendants), 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>
Scott Maine04c4542013-06-18 21:16:25 -0700145attribute 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>
Scott Main50403a22010-11-23 14:45:03 -0800149
Scott Main50403a22010-11-23 14:45:03 -0800150
Scott Main258a51e2011-10-25 12:11:40 -0700151<h3 id="Removing">Removing the action bar</h3>
Scott Main6ea0d2c2011-01-27 16:03:25 -0800152
Scott Maine04c4542013-06-18 21:16:25 -0700153<p>You can hide the action bar at runtime by calling {@link android.support.v7.app.ActionBar#hide}.
154For example:</p>
Scott Main50403a22010-11-23 14:45:03 -0800155
156<pre>
Scott Maine04c4542013-06-18 21:16:25 -0700157ActionBar actionBar = {@link android.support.v7.app.ActionBarActivity#getSupportActionBar()};
Scott Main6ea0d2c2011-01-27 16:03:25 -0800158actionBar.hide();
159</pre>
160
Scott Maine04c4542013-06-18 21:16:25 -0700161<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>
Scott Main6ea0d2c2011-01-27 16:03:25 -0800170
Scott Main258a51e2011-10-25 12:11:40 -0700171<p>Beware that hiding and removing the action bar causes your activity to re-layout in order to
Scott Maine04c4542013-06-18 21:16:25 -0700172account 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
Scott Main258a51e2011-10-25 12:11:40 -0700175way, your layout remains fixed when the action bar hides and re-appears. To enable overlay mode,
Scott Maine04c4542013-06-18 21:16:25 -0700176create 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
Scott Main258a51e2011-10-25 12:11:40 -0700179href="#Style">Styling the Action Bar</a>.</p>
180
Scott Maine04c4542013-06-18 21:16:25 -0700181
182<h3 id="Logo">Using a logo instead of an icon</h3>
183
184<p>By default, the system uses your application icon in the action bar, as specified by the <a
185href="{@docRoot}guide/topics/manifest/application-element.html#icon">{@code icon}</a>
186attribute in the <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code
187&lt;application&gt;}</a> or <a
188href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
189&lt;activity&gt;}</a> element. However, if you also specify the <a
190href="{@docRoot}guide/topics/manifest/application-element.html#logo">{@code logo}</a>
191attribute, then the action bar uses the logo image instead of the icon.</p>
192
193<p>A logo should usually be wider than the icon, but should not include unnecessary text. You
194should generally use a logo only when it represents your brand in a traditional format that users
195recognize. A good example is the YouTube app's logo&mdash;the logo represents the expected user
196brand, whereas the app's icon is a modified version that conforms to the square requirement
197for the launcher icon.</p>
198
Scott Main258a51e2011-10-25 12:11:40 -0700199
Scott Main6ea0d2c2011-01-27 16:03:25 -0800200
Scott Main18439be2010-09-07 17:11:38 -0700201
202<h2 id="ActionItems">Adding Action Items</h2>
203
Scott Maine04c4542013-06-18 21:16:25 -0700204<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>
Scott Main18439be2010-09-07 17:11:38 -0700208</div>
209
Scott Maine04c4542013-06-18 21:16:25 -0700210<p>The action bar provides users access to the most important action
211items relating to the app's current
212context. Those that appear directly in the action bar with an icon and/or text are known
213as <em>action buttons</em>. Actions that can't fit in the action bar or aren't
214important enough are hidden in the action overflow.
215The user can reveal a list of the other actions by pressing the overflow button
216on the right side (or the device <em>Menu</em> button, if available).</p>
217
218<p>When your activity starts, the system populates the action items by calling your activity's
219{@link android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()} method. Use this
220method to inflate a <a
221href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a> that defines all the
222action items. For example, here's a menu resource defining a couple of menu items:</p>
223
224<p class="code-caption">res/menu/main_activity_actions.xml</p>
225<pre>
226&lt;menu xmlns:android="http://schemas.android.com/apk/res/android" >
227 &lt;item android:id="@+id/action_search"
228 android:icon="@drawable/ic_action_search"
229 android:title="@string/action_search"/&gt;
230 &lt;item android:id="@+id/action_compose"
231 android:icon="@drawable/ic_action_compose"
232 android:title="@string/action_compose" /&gt;
233&lt;/menu&gt;
234</pre>
235
236<p>Then in your activity's {@link android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()}
237method, inflate the menu resource into the given {@link android.view.Menu}
238to add each item to the action bar:</p>
Scott Main6ea0d2c2011-01-27 16:03:25 -0800239
Scott Main258a51e2011-10-25 12:11:40 -0700240<pre>
241&#64;Override
242public boolean onCreateOptionsMenu(Menu menu) {
Scott Maine04c4542013-06-18 21:16:25 -0700243 // Inflate the menu items for use in the action bar
Scott Main258a51e2011-10-25 12:11:40 -0700244 MenuInflater inflater = getMenuInflater();
Scott Maine04c4542013-06-18 21:16:25 -0700245 inflater.inflate(R.menu.main_activity_actions, menu);
246 return super.onCreateOptionsMenu(menu);
Scott Main258a51e2011-10-25 12:11:40 -0700247}
248</pre>
249
Scott Maine04c4542013-06-18 21:16:25 -0700250<p>To request that an item appear directly in the action bar
251as an action button, include {@code
252showAsAction="ifRoom"} in the {@code &lt;item&gt;} tag. For example:</p>
Scott Main6ea0d2c2011-01-27 16:03:25 -0800253
Scott Maine04c4542013-06-18 21:16:25 -0700254<pre>
255&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"
Scott Main84f2a0f2013-07-24 07:57:05 -0700256 <strong>xmlns:yourapp="http://schemas.android.com/apk/res-auto"</strong> >
Scott Maine04c4542013-06-18 21:16:25 -0700257 &lt;item android:id="@+id/action_search"
258 android:icon="@drawable/ic_action_search"
259 android:title="@string/action_search"
Scott Main84f2a0f2013-07-24 07:57:05 -0700260 <strong>yourapp:showAsAction="ifRoom"</strong> /&gt;
Scott Maine04c4542013-06-18 21:16:25 -0700261 ...
262&lt;/menu&gt;
263</pre>
264
265<p>If there's not enough room for the item in the action bar, it will appear in the action
266overflow.</p>
267
268
269<div class="note" id="XmlAttributes">
270<p><strong>Using XML attributes from the support library</strong></p>
271Notice that the {@code showAsAction} attribute above uses a custom namespace defined in the
272{@code &lt;menu>} tag. This is necessary when using any XML attributes defined by the support
273library, because these attributes do not exist in the Android framework on older devices.
274So you must use your own namespace as a prefix for all attributes defined by the support library.
275</p>
276</div>
277
278<p>If your menu item supplies both a title and an icon&mdash;with the {@code title} and
279{@code icon} attributes&mdash;then the action item shows only the icon by default. If you
280want to display the text title, add {@code "withText"} to the {@code showAsAction}
Scott Main258a51e2011-10-25 12:11:40 -0700281attribute. For example:</p>
Scott Main18439be2010-09-07 17:11:38 -0700282
Scott Main18439be2010-09-07 17:11:38 -0700283<pre>
Scott Main84f2a0f2013-07-24 07:57:05 -0700284&lt;item yourapp:showAsAction="ifRoom|withText" ... /&gt;
Scott Main18439be2010-09-07 17:11:38 -0700285</pre>
286
Scott Main258a51e2011-10-25 12:11:40 -0700287<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>
Scott Main18439be2010-09-07 17:11:38 -0700290
Scott Maine04c4542013-06-18 21:16:25 -0700291<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>
Scott Main258a51e2011-10-25 12:11:40 -0700293<ul>
294 <li>If there's not enough room in the action bar for the action item, the menu item appears
Scott Maine04c4542013-06-18 21:16:25 -0700295in the overflow where only the title appears.</li>
Scott Main258a51e2011-10-25 12:11:40 -0700296 <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
Scott Maine04c4542013-06-18 21:16:25 -0700298tool-tip that displays the action title.</li>
Scott Main258a51e2011-10-25 12:11:40 -0700299</ul>
Scott Main18439be2010-09-07 17:11:38 -0700300
Scott Maine04c4542013-06-18 21:16:25 -0700301<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>
Scott Main18439be2010-09-07 17:11:38 -0700305
Scott Maine04c4542013-06-18 21:16:25 -0700306<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>
Scott Main258a51e2011-10-25 12:11:40 -0700313
314
315
316
Scott Maine04c4542013-06-18 21:16:25 -0700317<h3 id="ActionEvents">Handling clicks on action items</h3>
Scott Main258a51e2011-10-25 12:11:40 -0700318
Scott Maine04c4542013-06-18 21:16:25 -0700319<p>When the user presses an action, the system calls your activity's {@link
320android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} method. Using the
321{@link android.view.MenuItem} passed to this method, you can identify the action by calling {@link
322android.view.MenuItem#getItemId()}. This returns the unique ID provided by the {@code &lt;item&gt;}
323tag's {@code id} attribute so you can perform the appropriate action. For example:</p>
Scott Main18439be2010-09-07 17:11:38 -0700324
325<pre>
326&#64;Override
327public boolean onOptionsItemSelected(MenuItem item) {
Scott Maine04c4542013-06-18 21:16:25 -0700328 // Handle presses on the action bar items
Scott Main18439be2010-09-07 17:11:38 -0700329 switch (item.getItemId()) {
Scott Maine04c4542013-06-18 21:16:25 -0700330 case R.id.action_search:
331 openSearch();
332 return true;
333 case R.id.action_compose:
334 composeMessage();
Scott Main6ea0d2c2011-01-27 16:03:25 -0800335 return true;
336 default:
337 return super.onOptionsItemSelected(item);
Scott Main18439be2010-09-07 17:11:38 -0700338 }
Scott Main18439be2010-09-07 17:11:38 -0700339}
340</pre>
341
Scott Maine04c4542013-06-18 21:16:25 -0700342<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>
Scott Main18439be2010-09-07 17:11:38 -0700352
Scott Maine04c4542013-06-18 21:16:25 -0700353
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>
Scott Main84f2a0f2013-07-24 07:57:05 -0700375 <li>Add {@code uiOptions="splitActionBarWhenNarrow"} to each
376<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
377element or to the
Scott Maine04c4542013-06-18 21:16:25 -0700378<a href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>
Scott Main84f2a0f2013-07-24 07:57:05 -0700379element. This attribute is understood only by API level 14 and higher (it is ignored
380by older versions).</li>
381 <li>To support older versions, add a <a
382 href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code &lt;meta-data>}</a>
383 element as a child of each
384 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
385 element that declares the same value for {@code "android.support.UI_OPTIONS"}.</li>
386</ol>
Scott Main258a51e2011-10-25 12:11:40 -0700387
Scott Main84f2a0f2013-07-24 07:57:05 -0700388<p>For example:</p>
Scott Main258a51e2011-10-25 12:11:40 -0700389
Scott Main84f2a0f2013-07-24 07:57:05 -0700390<pre>
Scott Maine04c4542013-06-18 21:16:25 -0700391&lt;manifest ...>
Scott Main84f2a0f2013-07-24 07:57:05 -0700392 &lt;activity uiOptions="splitActionBarWhenNarrow" ... >
393 &lt;meta-data android:name="android.support.UI_OPTIONS"
394 android:value="splitActionBarWhenNarrow" />
395 &lt;/activity>
Scott Main943895b2013-07-24 11:03:04 -0700396&lt;/manifest>
Scott Maine04c4542013-06-18 21:16:25 -0700397</pre>
Scott Maine04c4542013-06-18 21:16:25 -0700398
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>
Scott Main258a51e2011-10-25 12:11:40 -0700406
407
408
Scott Maine04c4542013-06-18 21:16:25 -0700409<h2 id="Home">Navigating Up with the App Icon</h2>
Scott Main258a51e2011-10-25 12:11:40 -0700410
Scott Maine04c4542013-06-18 21:16:25 -0700411<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>
Scott Main258a51e2011-10-25 12:11:40 -0700421</div>
422
Scott Maine04c4542013-06-18 21:16:25 -0700423<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>
Scott Main258a51e2011-10-25 12:11:40 -0700427
Scott Maine04c4542013-06-18 21:16:25 -0700428<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>
Scott Main258a51e2011-10-25 12:11:40 -0700433
Scott Maine04c4542013-06-18 21:16:25 -0700434<p>To enable the app icon as an <em>Up</em> button, call {@link
435android.support.v7.app.ActionBar#setDisplayHomeAsUpEnabled setDisplayHomeAsUpEnabled()}.
436For example:</p>
Scott Main258a51e2011-10-25 12:11:40 -0700437
438<pre>
Scott Maine04c4542013-06-18 21:16:25 -0700439&#64;Override
Scott Main258a51e2011-10-25 12:11:40 -0700440protected void onCreate(Bundle savedInstanceState) {
441 super.onCreate(savedInstanceState);
Scott Maine04c4542013-06-18 21:16:25 -0700442 setContentView(R.layout.activity_details);
Scott Main258a51e2011-10-25 12:11:40 -0700443
Scott Maine04c4542013-06-18 21:16:25 -0700444 ActionBar actionBar = getSupportActionBar();
Scott Main6ea0d2c2011-01-27 16:03:25 -0800445 actionBar.setDisplayHomeAsUpEnabled(true);
Scott Main258a51e2011-10-25 12:11:40 -0700446 ...
Scott Main18439be2010-09-07 17:11:38 -0700447}
448</pre>
449
Scott Maine04c4542013-06-18 21:16:25 -0700450<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>
Scott Main258a51e2011-10-25 12:11:40 -0700453
Scott Maine04c4542013-06-18 21:16:25 -0700454<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>
Scott Main258a51e2011-10-25 12:11:40 -0700459
Scott Maine04c4542013-06-18 21:16:25 -0700460 <p>Beginning in Android 4.1 (API level 16), you can declare the parent with the <a href=
461"{@docRoot}guide/topics/manifest/activity-element.html#parent">{@code parentActivityName}</a>
462attribute in the <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
463&lt;activity&gt;}</a> element.</p>
464 <p>To support older devices with the support library, also
465include a <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code
466&lt;meta-data&gt;}</a> element that specifies
467the parent activity as the value for {@code android.support.PARENT_ACTIVITY}. For example:</p>
468<pre>
469&lt;application ... >
470 ...
471 &lt;!-- The main/home activity (has no parent activity) -->
472 &lt;activity
473 android:name="com.example.myfirstapp.MainActivity" ...>
474 ...
475 &lt;/activity>
476 &lt;!-- A child of the main activity -->
477 &lt;activity
478 android:name="com.example.myfirstapp.DisplayMessageActivity"
479 android:label="&#64;string/title_activity_display_message"
480 android:parentActivityName="com.example.myfirstapp.MainActivity" >
481 &lt;!-- Parent activity meta-data to support API level 7+ -->
482 &lt;meta-data
483 android:name="android.support.PARENT_ACTIVITY"
484 android:value="com.example.myfirstapp.MainActivity" />
485 &lt;/activity>
486&lt;/application>
487</pre>
Scott Main6ea0d2c2011-01-27 16:03:25 -0800488
Scott Maine04c4542013-06-18 21:16:25 -0700489 <p>Once the parent activity is specified in the manifest like this and you enable the <em>Up</em>
490 button with {@link
491android.support.v7.app.ActionBar#setDisplayHomeAsUpEnabled setDisplayHomeAsUpEnabled()}, your work
492is done and the action bar properly navigates up.</p>
493 </li>
494
495
496 <li><strong>Or, override {@link
497android.support.v7.app.ActionBarActivity#getSupportParentActivityIntent()} and {@link
498android.support.v7.app.ActionBarActivity#onCreateSupportNavigateUpTaskStack
499onCreateSupportNavigateUpTaskStack()} in your activity</strong>.</li>
500
501 <p>This is appropriate when <strong>the parent activity may be different</strong> depending
502 on how the user arrived at the current screen. That is, if there are many paths that the user
503 could have taken to reach the current screen, the <em>Up</em> button should navigate
504 backward along the path the user actually followed to get there.</p>
505
506 <p>The system calls {@link
507android.support.v7.app.ActionBarActivity#getSupportParentActivityIntent()} when the user presses
508the <em>Up</em> button while navigating your app (within your app's own task). If the activity that
509should open upon up navigation differs depending on how the user arrived at the current location,
510then you should override this method to return the {@link
511android.content.Intent} that starts the appropriate parent activity.</p>
512
513 <p>The system calls {@link
514android.support.v7.app.ActionBarActivity#onCreateSupportNavigateUpTaskStack
515onCreateSupportNavigateUpTaskStack()} for your activity when the user presses the <em>Up</em>
516button while your activity is running in a task that does <em>not</em> belong to your app. Thus,
517you must use the {@link android.support.v4.app.TaskStackBuilder} passed to this method to construct
518the appropriate back stack that should be synthesized when the user navigates up.</p>
519
520 <p>Even if you override {@link
521android.support.v7.app.ActionBarActivity#getSupportParentActivityIntent()} to specify up navigation
522as the user navigates your app, you can avoid the need to implement {@link
523android.support.v7.app.ActionBarActivity#onCreateSupportNavigateUpTaskStack
524onCreateSupportNavigateUpTaskStack()} by declaring "default" parent activities in the manifest file
525as shown above. Then the default implementation of {@link
526android.support.v7.app.ActionBarActivity#onCreateSupportNavigateUpTaskStack
527onCreateSupportNavigateUpTaskStack()} will synthesize a back stack based on the parent activities
528declared in the manifest.</p>
529
530 </li>
531</ul>
532
533<p class="note"><strong>Note:</strong>
534If you've built your app hierarchy using a series of fragments instead of multiple
535activities, then neither of the above options will work. Instead, to navigate up through your
536fragments, override {@link android.support.v7.app.ActionBarActivity#onSupportNavigateUp()}
537to perform the appropriate fragment transaction&mdash;usually by popping
538the current fragment from the back stack by calling {@link
539android.support.v4.app.FragmentManager#popBackStack()}.</p>
540
541<p>For more information about implementing <em>Up</em> navigation, read
542<a href="{@docRoot}training/implementing-navigation/ancestral.html">Providing Up Navigation</a>.</p>
Scott Main18439be2010-09-07 17:11:38 -0700543
544
Scott Main50403a22010-11-23 14:45:03 -0800545
546<h2 id="ActionView">Adding an Action View</h2>
547
Scott Maine04c4542013-06-18 21:16:25 -0700548<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>
Scott Main50403a22010-11-23 14:45:03 -0800552</div>
553
Scott Main6ea0d2c2011-01-27 16:03:25 -0800554
Scott Maine04c4542013-06-18 21:16:25 -0700555<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>
Scott Main50403a22010-11-23 14:45:03 -0800561
Scott Maine04c4542013-06-18 21:16:25 -0700562<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>
Scott Main50403a22010-11-23 14:45:03 -0800566
Scott Main50403a22010-11-23 14:45:03 -0800567<pre>
Scott Main6ea0d2c2011-01-27 16:03:25 -0800568&lt;?xml version="1.0" encoding="utf-8"?>
Scott Maine04c4542013-06-18 21:16:25 -0700569&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"
Scott Main84f2a0f2013-07-24 07:57:05 -0700570 xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
Scott Maine04c4542013-06-18 21:16:25 -0700571 &lt;item android:id="@+id/action_search"
572 android:title="@string/action_search"
573 android:icon="@drawable/ic_action_search"
Scott Main84f2a0f2013-07-24 07:57:05 -0700574 yourapp:showAsAction="ifRoom|collapseActionView"
575 <b>yourapp:actionViewClass="android.support.v7.widget.SearchView"</b> /&gt;
Scott Main6ea0d2c2011-01-27 16:03:25 -0800576&lt;/menu>
577</pre>
Scott Main6ea0d2c2011-01-27 16:03:25 -0800578
Scott Maine04c4542013-06-18 21:16:25 -0700579<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>
Scott Main50403a22010-11-23 14:45:03 -0800583
Scott Maine04c4542013-06-18 21:16:25 -0700584<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
Scott Main50403a22010-11-23 14:45:03 -0800591
592<pre>
593&#64;Override
594public boolean onCreateOptionsMenu(Menu menu) {
Scott Maine04c4542013-06-18 21:16:25 -0700595 getMenuInflater().inflate(R.menu.main_activity_actions, menu);
596 MenuItem searchItem = menu.findItem(R.id.action_search);
597 SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
Scott Main258a51e2011-10-25 12:11:40 -0700598 // Configure the search info and add any event listeners
599 ...
600 return super.onCreateOptionsMenu(menu);
Scott Main50403a22010-11-23 14:45:03 -0800601}
602</pre>
603
Scott Maine04c4542013-06-18 21:16:25 -0700604<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
Scott Mainabdf0d52011-02-08 10:20:27 -0800611<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>
Scott Main50403a22010-11-23 14:45:03 -0800613
614
Scott Maine04c4542013-06-18 21:16:25 -0700615
Scott Main258a51e2011-10-25 12:11:40 -0700616<h3 id="ActionViewCollapsing">Handling collapsible action views</h3>
Scott Main50403a22010-11-23 14:45:03 -0800617
Scott Maine04c4542013-06-18 21:16:25 -0700618<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}
Scott Main258a51e2011-10-25 12:11:40 -0700623attribute, as shown in the XML above.</p>
Scott Main18439be2010-09-07 17:11:38 -0700624
Scott Maine04c4542013-06-18 21:16:25 -0700625<p>Because the system expands the action view when the user selects the action, you
Scott Main258a51e2011-10-25 12:11:40 -0700626<em>do not</em> need to respond to the item in the {@link
Scott Maine04c4542013-06-18 21:16:25 -0700627android.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>
Scott Main258a51e2011-10-25 12:11:40 -0700631
Scott Maine04c4542013-06-18 21:16:25 -0700632<p>The system also collapses your action view when the user presses the <em>Up</em> button
633or <em>Back</em> button.</p>
Scott Main258a51e2011-10-25 12:11:40 -0700634
635<p>If you need to update your activity based on the visibility of your action view, you can receive
Scott Maine04c4542013-06-18 21:16:25 -0700636callbacks 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
Scott Main258a51e2011-10-25 12:11:40 -0700641
Scott Main18439be2010-09-07 17:11:38 -0700642<pre>
Scott Main258a51e2011-10-25 12:11:40 -0700643&#64;Override
644public boolean onCreateOptionsMenu(Menu menu) {
645 getMenuInflater().inflate(R.menu.options, menu);
646 MenuItem menuItem = menu.findItem(R.id.actionItem);
647 ...
Scott Main18439be2010-09-07 17:11:38 -0700648
Scott Maine04c4542013-06-18 21:16:25 -0700649 // 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() {
Scott Main258a51e2011-10-25 12:11:40 -0700652 &#64;Override
653 public boolean onMenuItemActionCollapse(MenuItem item) {
654 // Do something when collapsed
655 return true; // Return true to collapse action view
656 }
657
658 &#64;Override
659 public boolean onMenuItemActionExpand(MenuItem item) {
660 // Do something when expanded
661 return true; // Return true to expand action view
662 }
663 });
664}
665</pre>
666
667
668
669
670<h2 id="ActionProvider">Adding an Action Provider</h2>
671
Scott Maine04c4542013-06-18 21:16:25 -0700672<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>
Scott Main258a51e2011-10-25 12:11:40 -0700676</div>
677
Scott Maine04c4542013-06-18 21:16:25 -0700678<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>
Scott Main258a51e2011-10-25 12:11:40 -0700682
Scott Maine04c4542013-06-18 21:16:25 -0700683<p>To declare an action provider, supply the {@code actionViewClass} attribute in the
684menu {@code &lt;item>} tag with a fully-qualified class name for an
685{@link android.support.v4.view.ActionProvider}.</p>
Scott Main258a51e2011-10-25 12:11:40 -0700686
Scott Maine04c4542013-06-18 21:16:25 -0700687<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>
Scott Main258a51e2011-10-25 12:11:40 -0700692
Scott Maine04c4542013-06-18 21:16:25 -0700693<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>
Scott Main258a51e2011-10-25 12:11:40 -0700701
Scott Main258a51e2011-10-25 12:11:40 -0700702
Scott Maine04c4542013-06-18 21:16:25 -0700703<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>
Scott Main258a51e2011-10-25 12:11:40 -0700706
707
708
709<h3 id="ShareActionProvider">Using the ShareActionProvider</h3>
710
Scott Maine04c4542013-06-18 21:16:25 -0700711<p>To add a "share" action with {@link android.support.v7.widget.ShareActionProvider},
712define the {@code actionProviderClass} for an {@code &lt;item&gt;} tag with
713the {@link android.support.v7.widget.ShareActionProvider} class. For example:</p>
Scott Main258a51e2011-10-25 12:11:40 -0700714
Scott Maine04c4542013-06-18 21:16:25 -0700715<pre>
716&lt;?xml version="1.0" encoding="utf-8"?>
717&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"
Scott Main84f2a0f2013-07-24 07:57:05 -0700718 xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
Scott Maine04c4542013-06-18 21:16:25 -0700719 &lt;item android:id="@+id/action_share"
720 android:title="@string/share"
Scott Main84f2a0f2013-07-24 07:57:05 -0700721 yourapp:showAsAction="ifRoom"
722 <strong>yourapp:actionProviderClass="android.support.v7.widget.ShareActionProvider"</strong>
Scott Maine04c4542013-06-18 21:16:25 -0700723 /&gt;
724 ...
725&lt;/menu>
726</pre>
Scott Main258a51e2011-10-25 12:11:40 -0700727
Scott Maine04c4542013-06-18 21:16:25 -0700728<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>
Scott Main258a51e2011-10-25 12:11:40 -0700731
Scott Maine04c4542013-06-18 21:16:25 -0700732<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>
Scott Main258a51e2011-10-25 12:11:40 -0700741
Scott Maine04c4542013-06-18 21:16:25 -0700742<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>
Scott Main258a51e2011-10-25 12:11:40 -0700748
Scott Maine04c4542013-06-18 21:16:25 -0700749<p>For example:</p>
Scott Main258a51e2011-10-25 12:11:40 -0700750
751<pre>
752private ShareActionProvider mShareActionProvider;
Scott Main258a51e2011-10-25 12:11:40 -0700753
754&#64;Override
755public boolean onCreateOptionsMenu(Menu menu) {
Scott Maine04c4542013-06-18 21:16:25 -0700756 getMenuInflater().inflate(R.menu.main_activity_actions, menu);
Scott Main258a51e2011-10-25 12:11:40 -0700757
Scott Maine04c4542013-06-18 21:16:25 -0700758 // 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());
Scott Main258a51e2011-10-25 12:11:40 -0700763
Scott Maine04c4542013-06-18 21:16:25 -0700764 return super.onCreateOptionsMenu(menu);
Scott Main258a51e2011-10-25 12:11:40 -0700765}
Scott Maine04c4542013-06-18 21:16:25 -0700766
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
Scott Main2edf3722013-07-23 13:52:05 -0700770 * mShareActionProvider.{@link android.support.v7.widget.ShareActionProvider#setShareIntent setShareIntent()}
Scott Maine04c4542013-06-18 21:16:25 -0700771 */
772private Intent getDefaultIntent() {
773 Intent intent = new Intent(Intent.ACTION_SEND);
774 intent.setType("image/*");
775 return intent;
776}
Scott Main258a51e2011-10-25 12:11:40 -0700777</pre>
778
Scott Maine04c4542013-06-18 21:16:25 -0700779<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
Scott Main258a51e2011-10-25 12:11:40 -0700781android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} callback method.</p>
782
Scott Maine04c4542013-06-18 21:16:25 -0700783
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
Scott Main258a51e2011-10-25 12:11:40 -0700806
807
808
809<h3 id="CreatingActionProvider">Creating a custom action provider</h3>
810
Scott Maine04c4542013-06-18 21:16:25 -0700811<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>
Scott Main258a51e2011-10-25 12:11:40 -0700817
Scott Maine04c4542013-06-18 21:16:25 -0700818<p>To create your own action provider for a different action, simply extend the
819{@link android.support.v4.view.ActionProvider} class and implement
Scott Main258a51e2011-10-25 12:11:40 -0700820its callback methods as appropriate. Most importantly, you should implement the following:</p>
821
822<dl>
Scott Maine04c4542013-06-18 21:16:25 -0700823 <dt>{@link android.support.v4.view.ActionProvider#ActionProvider ActionProvider()}</dt>
Scott Main258a51e2011-10-25 12:11:40 -0700824 <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
Scott Maine04c4542013-06-18 21:16:25 -0700827 <dt>{@link android.support.v4.view.ActionProvider#onCreateActionView(MenuItem)}</dt>
Scott Main258a51e2011-10-25 12:11:40 -0700828 <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>
Scott Maine04c4542013-06-18 21:16:25 -0700833public View onCreateActionView(MenuItem forItem) {
Scott Main258a51e2011-10-25 12:11:40 -0700834 // Inflate the action view to be shown on the action bar.
835 LayoutInflater layoutInflater = LayoutInflater.from(mContext);
836 View view = layoutInflater.inflate(R.layout.action_provider, null);
837 ImageButton button = (ImageButton) view.findViewById(R.id.button);
838 button.setOnClickListener(new View.OnClickListener() {
839 &#064;Override
840 public void onClick(View v) {
841 // Do something...
842 }
843 });
844 return view;
845}
846</pre>
847</dd>
848
Scott Maine04c4542013-06-18 21:16:25 -0700849 <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
Scott Main258a51e2011-10-25 12:11:40 -0700851action provider should perform a default action for the menu item.
852 <p>However, if your action provider provides a submenu, through the {@link
Scott Maine04c4542013-06-18 21:16:25 -0700853android.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
Scott Main258a51e2011-10-25 12:11:40 -0700856submenu.</p>
Scott Maine04c4542013-06-18 21:16:25 -0700857
Scott Main258a51e2011-10-25 12:11:40 -0700858 <p class="note"><strong>Note:</strong> An activity or a fragment that implements {@link
859android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} can override the action
Scott Maine04c4542013-06-18 21:16:25 -0700860provider'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
Scott Main258a51e2011-10-25 12:11:40 -0700864</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
Scott Maine04c4542013-06-18 21:16:25 -0700876<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>
Scott Main258a51e2011-10-25 12:11:40 -0700878
Scott Maine04c4542013-06-18 21:16:25 -0700879<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>
Scott Main258a51e2011-10-25 12:11:40 -0700897</div>
898
Scott Maine04c4542013-06-18 21:16:25 -0700899<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>
Scott Main258a51e2011-10-25 12:11:40 -0700906
Scott Maine04c4542013-06-18 21:16:25 -0700907<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>
Scott Main258a51e2011-10-25 12:11:40 -0700914
Scott Main258a51e2011-10-25 12:11:40 -0700915
916<p>Once you determine where the fragments appear in the layout, the basic procedure to add tabs
917is:</p>
918<ol>
Scott Maine04c4542013-06-18 21:16:25 -0700919 <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>
Scott Main258a51e2011-10-25 12:11:40 -0700929</ol>
930
Scott Maine04c4542013-06-18 21:16:25 -0700931<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
Scott Main258a51e2011-10-25 12:11:40 -0700935between each {@link android.app.ActionBar.Tab} and the appropriate {@link android.app.Fragment} that
Scott Maine04c4542013-06-18 21:16:25 -0700936it represents. There are several ways you
937can define the association, depending on your design.</p>
Scott Main258a51e2011-10-25 12:11:40 -0700938
939<p>For example, here's how you might implement the {@link android.app.ActionBar.TabListener}
940such that each tab uses its own instance of the listener:</p>
941<pre>
942public static class TabListener&lt;T extends Fragment> implements ActionBar.TabListener {
943 private Fragment mFragment;
944 private final Activity mActivity;
945 private final String mTag;
946 private final Class&lt;T> mClass;
947
948 /** Constructor used each time a new tab is created.
949 * @param activity The host Activity, used to instantiate the fragment
950 * @param tag The identifier tag for the fragment
951 * @param clz The fragment's Class, used to instantiate the fragment
952 */
953 public TabListener(Activity activity, String tag, Class&lt;T> clz) {
954 mActivity = activity;
955 mTag = tag;
956 mClass = clz;
Scott Main18439be2010-09-07 17:11:38 -0700957 }
958
Scott Main258a51e2011-10-25 12:11:40 -0700959 /* The following are each of the {@link android.app.ActionBar.TabListener} callbacks */
960
Scott Main18439be2010-09-07 17:11:38 -0700961 public void onTabSelected(Tab tab, FragmentTransaction ft) {
Scott Main258a51e2011-10-25 12:11:40 -0700962 // 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 }
Scott Main18439be2010-09-07 17:11:38 -0700971 }
972
Scott Main18439be2010-09-07 17:11:38 -0700973 public void onTabUnselected(Tab tab, FragmentTransaction ft) {
Scott Main258a51e2011-10-25 12:11:40 -0700974 if (mFragment != null) {
975 // Detach the fragment, because another one is being attached
976 ft.detach(mFragment);
977 }
Scott Main18439be2010-09-07 17:11:38 -0700978 }
979
Scott Main18439be2010-09-07 17:11:38 -0700980 public void onTabReselected(Tab tab, FragmentTransaction ft) {
Scott Main258a51e2011-10-25 12:11:40 -0700981 // User selected the already selected tab. Usually do nothing.
Scott Main18439be2010-09-07 17:11:38 -0700982 }
Scott Main18439be2010-09-07 17:11:38 -0700983}
984</pre>
Scott Main258a51e2011-10-25 12:11:40 -0700985
986<p class="caution"><strong>Caution:</strong> You <strong>must not</strong> call {@link
987android.app.FragmentTransaction#commit} for the fragment transaction in each of these
988callbacks&mdash;the system calls it for you and it may throw an exception if you call it yourself.
989You also <strong>cannot</strong> add these fragment transactions to the back stack.</p>
990
991<p>In this example, the listener simply attaches ({@link android.app.FragmentTransaction#attach
992attach()}) a fragment to the activity layout&mdash;or if not instantiated, creates the fragment and
993adds ({@link android.app.FragmentTransaction#add add()}) it to the layout (as a child of the {@code
994android.R.id.content} view group)&mdash;when the respective tab is selected, and detaches ({@link
995android.app.FragmentTransaction#detach detach()}) it when the tab is unselected.</p>
996
Scott Maine04c4542013-06-18 21:16:25 -0700997<p>All that remains is to create each {@link android.app.ActionBar.Tab} and add it to the {@link
Scott Main258a51e2011-10-25 12:11:40 -0700998android.app.ActionBar}. Additionally, you must call {@link
999android.app.ActionBar#setNavigationMode(int) setNavigationMode(NAVIGATION_MODE_TABS)} to make the
Scott Maine04c4542013-06-18 21:16:25 -07001000tabs visible.</p>
Scott Main258a51e2011-10-25 12:11:40 -07001001
1002<p>For example, the following code adds two tabs using the listener defined above:</p>
1003
Scott Main18439be2010-09-07 17:11:38 -07001004<pre>
1005&#64;Override
1006protected void onCreate(Bundle savedInstanceState) {
1007 super.onCreate(savedInstanceState);
Scott Main258a51e2011-10-25 12:11:40 -07001008 // Notice that setContentView() is not used, because we use the root
1009 // android.R.id.content as the container for each fragment
Scott Main18439be2010-09-07 17:11:38 -07001010
Scott Main258a51e2011-10-25 12:11:40 -07001011 // setup action bar for tabs
Scott Maine04c4542013-06-18 21:16:25 -07001012 ActionBar actionBar = getSupportActionBar();
Scott Main18439be2010-09-07 17:11:38 -07001013 actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
Scott Main6ea0d2c2011-01-27 16:03:25 -08001014 actionBar.setDisplayShowTitleEnabled(false);
Scott Main18439be2010-09-07 17:11:38 -07001015
Scott Main258a51e2011-10-25 12:11:40 -07001016 Tab tab = actionBar.newTab()
Scott Maine04c4542013-06-18 21:16:25 -07001017 .setText(R.string.artist)
1018 .setTabListener(new TabListener&lt;ArtistFragment>(
1019 this, "artist", ArtistFragment.class));
Scott Main258a51e2011-10-25 12:11:40 -07001020 actionBar.addTab(tab);
Scott Main18439be2010-09-07 17:11:38 -07001021
Scott Main258a51e2011-10-25 12:11:40 -07001022 tab = actionBar.newTab()
Scott Maine04c4542013-06-18 21:16:25 -07001023 .setText(R.string.album)
1024 .setTabListener(new TabListener&lt;AlbumFragment>(
1025 this, "album", AlbumFragment.class));
Scott Main258a51e2011-10-25 12:11:40 -07001026 actionBar.addTab(tab);
Scott Main18439be2010-09-07 17:11:38 -07001027}
1028</pre>
1029
Scott Main18439be2010-09-07 17:11:38 -07001030
Scott Maine04c4542013-06-18 21:16:25 -07001031<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>
Scott Main18439be2010-09-07 17:11:38 -07001037
Scott Main18439be2010-09-07 17:11:38 -07001038
Scott Main258a51e2011-10-25 12:11:40 -07001039<p class="caution"><strong>Caution:</strong> It's important that you save the state of each fragment
Scott Maine04c4542013-06-18 21:16:25 -07001040so 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
Scott Main50e990c2012-06-21 17:14:39 -07001043fragment, see the <a href="{@docRoot}guide/components/fragments.html">Fragments</a>
Scott Maine04c4542013-06-18 21:16:25 -07001044API 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>
Scott Main18439be2010-09-07 17:11:38 -07001055
1056
Scott Maine04c4542013-06-18 21:16:25 -07001057
Scott Main50403a22010-11-23 14:45:03 -08001058
Scott Main6ea0d2c2011-01-27 16:03:25 -08001059
Scott Main50403a22010-11-23 14:45:03 -08001060<h2 id="Dropdown">Adding Drop-down Navigation</h2>
1061
Scott Maine04c4542013-06-18 21:16:25 -07001062<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
Scott Main258a51e2011-10-25 12:11:40 -07001065action bar.</p>
Scott Main50403a22010-11-23 14:45:03 -08001066</div>
Scott Maine04c4542013-06-18 21:16:25 -07001067
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
Scott Main50403a22010-11-23 14:45:03 -08001076
Scott Main258a51e2011-10-25 12:11:40 -07001077<p>The basic procedure to enable drop-down navigation is:</p>
Scott Main50403a22010-11-23 14:45:03 -08001078
1079<ol>
1080 <li>Create a {@link android.widget.SpinnerAdapter} that provides the
Scott Main6ea0d2c2011-01-27 16:03:25 -08001081list of selectable items for the drop-down and the layout to use when drawing each item in the
1082list.</li>
Scott Maine04c4542013-06-18 21:16:25 -07001083 <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)}.
Scott Main50403a22010-11-23 14:45:03 -08001088 </li>
Scott Main258a51e2011-10-25 12:11:40 -07001089 <li>Set the callback for the drop-down list with {@link
Scott Maine04c4542013-06-18 21:16:25 -07001090android.support.v7.app.ActionBar#setListNavigationCallbacks setListNavigationCallbacks()}.
1091For example:
Scott Main50403a22010-11-23 14:45:03 -08001092<pre>
1093actionBar.setListNavigationCallbacks(mSpinnerAdapter, mNavigationCallback);
1094</pre>
1095<p>This method takes your {@link android.widget.SpinnerAdapter} and {@link
Scott Maine04c4542013-06-18 21:16:25 -07001096android.support.v7.app.ActionBar.OnNavigationListener}.</p>
Scott Main50403a22010-11-23 14:45:03 -08001097</li>
1098</ol>
1099
Scott Maine04c4542013-06-18 21:16:25 -07001100<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
Scott Main6ea0d2c2011-01-27 16:03:25 -08001103implementing 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
Scott Maine04c4542013-06-18 21:16:25 -07001105information). 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>
Scott Main50403a22010-11-23 14:45:03 -08001108
1109
Scott Main50403a22010-11-23 14:45:03 -08001110
Scott Main6ea0d2c2011-01-27 16:03:25 -08001111<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,
Scott Main258a51e2011-10-25 12:11:40 -07001121such as the drop-down list in the action bar. {@link android.widget.SpinnerAdapter} is an interface
Scott Main6ea0d2c2011-01-27 16:03:25 -08001122that you can implement, but Android includes some useful implementations that you can extend, such
1123as {@link android.widget.ArrayAdapter} and {@link
Scott Main50403a22010-11-23 14:45:03 -08001124android.widget.SimpleCursorAdapter}. For example, here's an easy way to create a {@link
Scott Main6ea0d2c2011-01-27 16:03:25 -08001125android.widget.SpinnerAdapter} by using {@link android.widget.ArrayAdapter} implementation, which
1126uses a string array as the data source:</p>
Scott Main50403a22010-11-23 14:45:03 -08001127
1128<pre>
1129SpinnerAdapter mSpinnerAdapter = ArrayAdapter.createFromResource(this, R.array.action_list,
1130 android.R.layout.simple_spinner_dropdown_item);
1131</pre>
1132
Scott Main6ea0d2c2011-01-27 16:03:25 -08001133<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>
Scott Main50403a22010-11-23 14:45:03 -08001136
1137<p>A <a href="{@docRoot}guide/topics/resources/string-resource.html#StringArray">string array</a>
Scott Main6ea0d2c2011-01-27 16:03:25 -08001138defined in a resource looks like this:</p>
Scott Main50403a22010-11-23 14:45:03 -08001139
1140<pre>
1141&lt;?xml version="1.0" encoding="utf-8"?&gt;
1142&lt;resources&gt;
1143 &lt;string-array name="action_list"&gt;
1144 &lt;item&gt;Mercury&lt;/item&gt;
1145 &lt;item&gt;Venus&lt;/item&gt;
1146 &lt;item&gt;Earth&lt;/item&gt;
1147 &lt;/string-array&gt;
1148&lt;/pre&gt;
1149</pre>
1150
Scott Main6ea0d2c2011-01-27 16:03:25 -08001151<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>
Scott Main50403a22010-11-23 14:45:03 -08001156
Scott Main50403a22010-11-23 14:45:03 -08001157
Adam Powell8515ee82010-11-30 14:09:55 -08001158<p>Your implementation of {@link android.app.ActionBar.OnNavigationListener} is where you handle
Scott Main50403a22010-11-23 14:45:03 -08001159fragment changes or other modifications to your activity when the user selects an item from the
Scott Main6ea0d2c2011-01-27 16:03:25 -08001160drop-down list. There's only one callback method to implement in the listener: {@link
Adam Powell8515ee82010-11-30 14:09:55 -08001161android.app.ActionBar.OnNavigationListener#onNavigationItemSelected onNavigationItemSelected()}.</p>
Scott Main50403a22010-11-23 14:45:03 -08001162
1163<p>The {@link
Adam Powell8515ee82010-11-30 14:09:55 -08001164android.app.ActionBar.OnNavigationListener#onNavigationItemSelected onNavigationItemSelected()}
Scott Main6ea0d2c2011-01-27 16:03:25 -08001165method receives the position of the item in the list and a unique item ID provided by the {@link
Scott Main50403a22010-11-23 14:45:03 -08001166android.widget.SpinnerAdapter}.</p>
1167
1168<p>Here's an example that instantiates an anonymous implementation of {@link
Scott Main6ea0d2c2011-01-27 16:03:25 -08001169android.app.ActionBar.OnNavigationListener OnNavigationListener}, which inserts a {@link
1170android.app.Fragment} into the
Scott Main50403a22010-11-23 14:45:03 -08001171layout container identified by {@code R.id.fragment_container}:</p>
1172
1173<pre>
Adam Powell8515ee82010-11-30 14:09:55 -08001174mOnNavigationListener = new OnNavigationListener() {
Scott Main50403a22010-11-23 14:45:03 -08001175 // Get the same strings provided for the drop-down's ArrayAdapter
1176 String[] strings = getResources().getStringArray(R.array.action_list);
1177
1178 &#64;Override
1179 public boolean onNavigationItemSelected(int position, long itemId) {
1180 // Create new fragment from our own Fragment class
1181 ListContentFragment newFragment = new ListContentFragment();
1182 FragmentTransaction ft = openFragmentTransaction();
1183 // Replace whatever is in the fragment container with this fragment
1184 // and give the fragment a tag name equal to the string at the position selected
1185 ft.replace(R.id.fragment_container, newFragment, strings[position]);
1186 // Apply changes
1187 ft.commit();
1188 return true;
1189 }
1190};
1191</pre>
1192
Scott Main6ea0d2c2011-01-27 16:03:25 -08001193<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>
Scott Main50403a22010-11-23 14:45:03 -08001197
Scott Main6ea0d2c2011-01-27 16:03:25 -08001198<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>
Scott Main50403a22010-11-23 14:45:03 -08001205
1206<pre>
1207public class ListContentFragment extends Fragment {
1208 private String mText;
1209
1210 &#64;Override
1211 public void onAttach(Activity activity) {
1212 // This is the first callback received; here we can set the text for
1213 // the fragment as defined by the tag specified during the fragment transaction
1214 super.onAttach(activity);
1215 mText = getTag();
1216 }
1217
1218 &#64;Override
1219 public View onCreateView(LayoutInflater inflater, ViewGroup container,
1220 Bundle savedInstanceState) {
1221 // This is called to define the layout for the fragment;
1222 // we just create a TextView and set its text to be the fragment tag
1223 TextView text = new TextView(getActivity());
1224 text.setText(mText);
1225 return text;
1226 }
1227}
1228</pre>
1229
Scott Main6ea0d2c2011-01-27 16:03:25 -08001230 </div><!-- end toggle-content-toggleme -->
1231
1232</div><!-- end toggle-content -->
1233
1234
1235
1236
1237
Scott Maine04c4542013-06-18 21:16:25 -07001238
1239
Scott Main6ea0d2c2011-01-27 16:03:25 -08001240<h2 id="Style">Styling the Action Bar</h2>
1241
Scott Maine04c4542013-06-18 21:16:25 -07001242<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>
Scott Main6ea0d2c2011-01-27 16:03:25 -08001247
Scott Maine04c4542013-06-18 21:16:25 -07001248<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>
Scott Main258a51e2011-10-25 12:11:40 -07001252
Scott Main258a51e2011-10-25 12:11:40 -07001253
1254
1255<h3 id="GeneralStyles">General appearance</h3>
Scott Main6ea0d2c2011-01-27 16:03:25 -08001256
1257<dl>
Scott Maine04c4542013-06-18 21:16:25 -07001258 <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>
Scott Main6ea0d2c2011-01-27 16:03:25 -08001300
Scott Main258a51e2011-10-25 12:11:40 -07001301 <dt>{@link android.R.attr#windowActionBarOverlay
Scott Maine04c4542013-06-18 21:16:25 -07001302 windowActionBarOverlay}</dt>
Scott Main258a51e2011-10-25 12:11:40 -07001303 <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>
Scott Maine04c4542013-06-18 21:16:25 -07001317 <p>When overlay mode is enabled, your activity layout has no awareness of the action bar lying on
Scott Main258a51e2011-10-25 12:11:40 -07001318top of it. So, you must be careful not to place any important information or UI components in the
Scott Maine04c4542013-06-18 21:16:25 -07001319area overlaid by the action bar. If appropriate, you can refer to the platform's value for {@link
Scott Main258a51e2011-10-25 12:11:40 -07001320android.R.attr#actionBarSize} to determine the height of the action bar, by referencing it
1321in your XML layout. For example:</p>
Scott Main6ea0d2c2011-01-27 16:03:25 -08001322<pre>
Scott Main258a51e2011-10-25 12:11:40 -07001323&lt;SomeView
1324 ...
1325 android:layout_marginTop="?android:attr/actionBarSize" /&gt;
Scott Main6ea0d2c2011-01-27 16:03:25 -08001326</pre>
Scott Main258a51e2011-10-25 12:11:40 -07001327 <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
Scott Maine04c4542013-06-18 21:16:25 -07001329called, 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
Scott Main258a51e2011-10-25 12:11:40 -07001336</dd>
Scott Main6ea0d2c2011-01-27 16:03:25 -08001337
1338</dl>
1339
Scott Main258a51e2011-10-25 12:11:40 -07001340
1341<h3 id="ActionItemStyles">Action items</h3>
1342
1343<dl>
1344 <dt>{@link android.R.attr#actionButtonStyle
Scott Maine04c4542013-06-18 21:16:25 -07001345 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>
Scott Main258a51e2011-10-25 12:11:40 -07001350
1351 <dt>{@link android.R.attr#actionBarItemBackground
Scott Maine04c4542013-06-18 21:16:25 -07001352 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>
Scott Main258a51e2011-10-25 12:11:40 -07001356
1357 <dt>{@link android.R.attr#itemBackground
Scott Maine04c4542013-06-18 21:16:25 -07001358 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>
Scott Main258a51e2011-10-25 12:11:40 -07001362
1363 <dt>{@link android.R.attr#actionBarDivider
Scott Maine04c4542013-06-18 21:16:25 -07001364 actionBarDivider}</dt>
1365 <dd>Defines a drawable resource for the divider between action items.</dd>
Scott Main258a51e2011-10-25 12:11:40 -07001366
1367 <dt>{@link android.R.attr#actionMenuTextColor
Scott Maine04c4542013-06-18 21:16:25 -07001368 actionMenuTextColor}</dt>
Scott Main258a51e2011-10-25 12:11:40 -07001369 <dd>Defines a color for text that appears in an action item.</dd>
1370
1371 <dt>{@link android.R.attr#actionMenuTextAppearance
Scott Maine04c4542013-06-18 21:16:25 -07001372 actionMenuTextAppearance}</dt>
Scott Main258a51e2011-10-25 12:11:40 -07001373 <dd>Defines a style resource for text that appears in an action item.</dd>
1374
1375 <dt>{@link android.R.attr#actionBarWidgetTheme
Scott Maine04c4542013-06-18 21:16:25 -07001376 actionBarWidgetTheme}</dt>
Scott Main258a51e2011-10-25 12:11:40 -07001377 <dd>Defines a theme resource for widgets that are inflated into the action bar as <a
Scott Maine04c4542013-06-18 21:16:25 -07001378href="#ActionView">action views</a>.</dd>
Scott Main258a51e2011-10-25 12:11:40 -07001379</dl>
1380
1381
1382<h3 id="NavigationStyles">Navigation tabs</h3>
1383
1384<dl>
1385 <dt>{@link android.R.attr#actionBarTabStyle
Scott Maine04c4542013-06-18 21:16:25 -07001386 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>
Scott Main258a51e2011-10-25 12:11:40 -07001391
1392 <dt>{@link android.R.attr#actionBarTabBarStyle
Scott Maine04c4542013-06-18 21:16:25 -07001393 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>
Scott Main258a51e2011-10-25 12:11:40 -07001398
1399 <dt>{@link android.R.attr#actionBarTabTextStyle
Scott Maine04c4542013-06-18 21:16:25 -07001400 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>
Scott Main258a51e2011-10-25 12:11:40 -07001405</dl>
1406
1407
1408<h3 id="DropDownStyles">Drop-down lists</h3>
1409
1410<dl>
1411 <dt>{@link android.R.attr#actionDropDownStyle
Scott Maine04c4542013-06-18 21:16:25 -07001412 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>
Scott Main258a51e2011-10-25 12:11:40 -07001418</dl>
1419
1420
Scott Maine04c4542013-06-18 21:16:25 -07001421<h3 id="StyleExample">Example theme</h3>
Scott Main258a51e2011-10-25 12:11:40 -07001422
Scott Maine04c4542013-06-18 21:16:25 -07001423<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>
Scott Main6ea0d2c2011-01-27 16:03:25 -08001431
1432<pre>
1433&lt;?xml version="1.0" encoding="utf-8"?>
1434&lt;resources>
1435 &lt;!-- the theme applied to the application or activity -->
Scott Maine04c4542013-06-18 21:16:25 -07001436 &lt;style name="CustomActionBarTheme"
1437 parent="&#64;style/Theme.AppCompat.Light">
1438 &lt;item name="android:actionBarStyle">&#64;style/MyActionBar&lt;/item>
1439 &lt;item name="android:actionBarTabTextStyle">&#64;style/TabTextStyle&lt;/item>
1440 &lt;item name="android:actionMenuTextColor">&#64;color/actionbar_text&lt;/item>
1441
1442 &lt;!-- Support library compatibility -->
1443 &lt;item name="actionBarStyle">&#64;style/MyActionBar&lt;/item>
1444 &lt;item name="actionBarTabTextStyle">&#64;style/TabTextStyle&lt;/item>
1445 &lt;item name="actionMenuTextColor">&#64;color/actionbar_text&lt;/item>
Scott Main6ea0d2c2011-01-27 16:03:25 -08001446 &lt;/style>
1447
Scott Maine04c4542013-06-18 21:16:25 -07001448 &lt;!-- general styles for the action bar -->
1449 &lt;style name="MyActionBar"
1450 parent="&#64;style/Widget.AppCompat.ActionBar">
1451 &lt;item name="android:titleTextStyle">&#64;style/TitleTextStyle&lt;/item>
1452 &lt;item name="android:background">&#64;drawable/actionbar_background&lt;/item>
1453 &lt;item name="android:backgroundStacked">&#64;drawable/actionbar_background&lt;/item>
1454 &lt;item name="android:backgroundSplit">&#64;drawable/actionbar_background&lt;/item>
1455
1456 &lt;!-- Support library compatibility -->
1457 &lt;item name="titleTextStyle">&#64;style/TitleTextStyle&lt;/item>
1458 &lt;item name="background">&#64;drawable/actionbar_background&lt;/item>
1459 &lt;item name="backgroundStacked">&#64;drawable/actionbar_background&lt;/item>
1460 &lt;item name="backgroundSplit">&#64;drawable/actionbar_background&lt;/item>
1461 &lt;/style>
1462
1463 &lt;!-- action bar title text -->
1464 &lt;style name="TitleTextStyle"
1465 parent="&#64;style/TextAppearance.AppCompat.Widget.ActionBar.Title">
1466 &lt;item name="android:textColor">&#64;color/actionbar_text&lt;/item>
1467 &lt;/style>
1468
1469 &lt;!-- action bar tab text -->
1470 &lt;style name="TabTextStyle"
1471 parent="&#64;style/Widget.AppCompat.ActionBar.TabText">
1472 &lt;item name="android:textColor">&#64;color/actionbar_text&lt;/item>
Scott Main6ea0d2c2011-01-27 16:03:25 -08001473 &lt;/style>
1474&lt;/resources>
Scott Maine04c4542013-06-18 21:16:25 -07001475
Scott Main6ea0d2c2011-01-27 16:03:25 -08001476</pre>
1477
Scott Maine04c4542013-06-18 21:16:25 -07001478<p>In your manifest file, you can apply the theme to your entire app:</p>
Scott Main6ea0d2c2011-01-27 16:03:25 -08001479
1480<pre>
Scott Maine04c4542013-06-18 21:16:25 -07001481&lt;application android:theme="&#64;style/CustomActionBarTheme" ... />
Scott Main6ea0d2c2011-01-27 16:03:25 -08001482</pre>
1483
Scott Maine04c4542013-06-18 21:16:25 -07001484<p>Or to individual activities:</p>
1485
1486<pre>
1487&lt;activity android:theme="&#64;style/CustomActionBarTheme" ... />
1488</pre>
1489
1490
1491<p class="caution"><strong>Caution:</strong> Be certain that each theme and style declares a parent
1492theme in the {@code &lt;style&gt;} tag, from which it inherits all styles not explicitly declared
1493by your theme. When modifying the action bar, using a parent theme is important so that you can
1494simply override the action bar styles you want to change without re-implementing the styles you
1495want to leave alone (such as text size or padding in action items).</p>
1496
Scott Main258a51e2011-10-25 12:11:40 -07001497<p>For more information about using style and theme resources in your application, read <a
Scott Mainb10b48f2011-09-13 16:40:52 -07001498href="{@docRoot}guide/topics/ui/themes.html">Styles and Themes</a>.</p>
Scott Main6ea0d2c2011-01-27 16:03:25 -08001499
Scott Main50403a22010-11-23 14:45:03 -08001500
Scott Main50403a22010-11-23 14:45:03 -08001501