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