User Interface >

Using the Action Bar

Quickview

  • A replacement for the title bar that includes the application icon and activity title
  • Provides action items from the Options Menu and modes of navigating around the application
  • Supports custom views, including an embedded search box
  • Requires API Level 11

In this document

  1. Adding the Action Bar
    1. Removing the Action Bar
  2. Adding Action Items
    1. Using the app icon as an action item
  3. Adding an Action View
  4. Adding Tabs
  5. Adding Drop-down Navigation
  6. Styling the Action Bar

Key classes

  1. ActionBar
  2. Menu

Related samples

  1. API Demos
  2. Honeycomb Gallery

See also

  1. Creating Menus

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:

  • Display items from the Options Menu directly in the Action Bar, as "action items"—providing instant access to key user actions.

    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.

  • Provide tabs for navigating between fragments.
  • Provide a drop-down list for navigation.
  • Provide interactive "action views" in place of action items (such as a search box).

Figure 1. A screenshot of the Action Bar in the Email application, containing action items to compose new email and refresh the inbox.

Adding the Action Bar

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 android:minSdkVersion or android:targetSdkVersion attribute in the <uses-sdk> element to "11" or greater. For example:

<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"
              android:targetSdkVersion="11" />
    <application ... >
        ...
    </application>
</manifest>

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.

However, if you want to use Action Bar APIs, such as to add tabs or modify Action Bar styles, you need to set the android:minSdkVersion to "11", so you can access the ActionBar class.

Removing the Action Bar

If you want to remove the Action Bar for a particular activity, set the activity theme to Theme.Holo.NoActionBar. For example:

<activity android:theme="@android:style/Theme.Holo.NoActionBar">

Tip: If you have a custom activity theme in which you'd like to remove the Action Bar, set the android:windowActionBar style property false. See Styling the Action Bar for more about Action Bar styles.

You can also hide the Action Bar at runtime by calling hide(), then show it again by calling show(). For example:

ActionBar actionBar = getActionBar();
actionBar.hide();

When the Action Bar hides, the system adjusts your activity content to fill all the available screen space.

Note: 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 getActionBar() will return null.

Adding Action Items

An action item is simply a menu item from the Options Menu 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.

Figure 2. A screenshot from an Action Bar with two action items and the overflow menu.

When the activity first starts, the system populates the Action Bar and overflow menu by calling onCreateOptionsMenu() for your activity. As discussed in the guide to Creating Menus, it's in this callback method that you define the Options Menu for the activity.

You can specify a menu item to appear as an action item—if there is room for it—from your menu resource by declaring android:showAsAction="ifRoom" for the <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).

You can also declare a menu item to appear as an action item from your application code, by calling setShowAsAction() on the MenuItem and passing SHOW_AS_ACTION_IF_ROOM.

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 withText to the android:showAsAction attribute or, in your application code, use the SHOW_AS_ACTION_WITH_TEXT flag when calling setShowAsAction(). Figure 2 shows an Action Bar that has two action items with text and the icon for the overflow menu.

Here's an example of how you can declare a menu item as an action item in a menu resource file:

<?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"
          android:showAsAction="ifRoom|withText" />
</menu>

In this case, both the ifRoom and withText flags are set, so that when this item appears as an action item, it includes the title text along with the icon.

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 onOptionsItemSelected(), passing the item ID.

Note: If you added the menu item from a fragment, then the respective onOptionsItemSelected() method is called for that fragment. However the activity gets a chance to handle it first, so the system calls onOptionsItemSelected() on the activity before calling the fragment.

You can also declare an item to always 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.

For more information about menus, see the Creating Menus developer guide.

Using the app icon as an action item

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.

Figure 3. Email's Action Bar, with the application icon on the left.

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.

When the user taps the icon, the system calls your activity's onOptionsItemSelected() method with the android.R.id.home ID. So, you need to add a condition to your onOptionsItemSelected() method to listen for android.R.id.home and perform the appropriate action, such as start the home activity or pop recent fragment transactions off the stack.

If you respond to the application icon by returning to the home activity, you should include the FLAG_ACTIVITY_CLEAR_TOP flag in the 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.

For example, here's an implementation of onOptionsItemSelected() that returns to the application's "home" activity:

@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);
    }
}

Using the app icon to navigate "up"

Figure 4. The standard icon for the Email application (top) and the "up" icon (bottom).

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).

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 setDisplayHomeAsUpEnabled(true) on your activity's ActionBar. When you do, the system draws your application icon with an arrow indicating the up behavior, as shown in figure 4.

For example, here's how you can show the application icon as an "up" action:

@Override
protected void onStart() {
    super.onStart();
    ActionBar actionBar = this.getActionBar();
    actionBar.setDisplayHomeAsUpEnabled(true);
}

Then, your activity should respond to the user tapping the icon, from the onOptionsItemSelected(), by listening for the android.R.id.home ID (as shown above). In this case, when navigating up, it's even more important that you use the FLAG_ACTIVITY_CLEAR_TOP flag in the Intent, so that you don't create a new instance of the parent activity if one already exists.

Adding an Action View

Figure 5. An action view with a SearchView widget.

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 SearchView widget in the Action Bar whenever the item is enabled as an action item.

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 search dialog, but if the item is placed in the Action Bar, the action view appears with a SearchView widget. Figure 4 shows an example of the SearchView widget in an action view.

The best way to declare an action view for an item is in your menu resource, using the android:actionLayout or android:actionViewClass attribute:

  • The value for android:actionLayout must be a resource pointer to a layout file. For example:
    <?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"
            android:actionLayout="@layout/searchview" />
    </menu>
    
  • The value for android:actionViewClass must be a fully-qualified class name for the View you want to use. For example:
    <?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"
            android:actionViewClass="android.widget.SearchView" />
    </menu>
    

You must include 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 android:showAsAction to "always".

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 onOptionsItemSelected() callback method. (For a guide to providing search functionality, see the Search documentation.)

When the activity first starts, the system populates the Action Bar and overflow menu by calling 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 findItem() with the ID of the menu item, then getActionView() on the returned MenuItem. For example, the search widget from the above samples is acquired like this:

@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);
}

For more information about enabling search in the Action Bar, see the Search developer guide.

Adding Tabs

Figure 6. Screenshot of tabs in the Action Bar, from the Honeycomb Gallery sample application.

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.

To begin, your layout must include a View in which each Fragment associated with a tab is displayed. Be sure the view has an ID that you can use to reference it from your code.

To add tabs to the Action Bar:

  1. Create an implementation of ActionBar.TabListener to handle the interaction events on the Action Bar tabs. You must implement all methods: onTabSelected(), onTabUnselected(), and onTabReselected().

    Each callback method passes the ActionBar.Tab that received the event and a FragmentTransaction for you to perform the fragment transactions (add or remove fragments).

    For example:

    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
        }
    
    }
    

    This implementation of ActionBar.TabListener adds a constructor that saves the Fragment associated with a tab so that each callback can add or remove that fragment.

  2. Get the ActionBar for your activity by calling getActionBar() from your Activity, during onCreate() (but be sure you do so after you've called setContentView()).
  3. Call setNavigationMode(NAVIGATION_MODE_TABS) to enable tab mode for the ActionBar.
  4. Create each tab for the Action Bar:
    1. Create a new ActionBar.Tab by calling newTab() on the ActionBar.
    2. Add title text and/or an icon for the tab by calling setText() and/or setIcon().

      Tip: These methods return the same ActionBar.Tab instance, so you can chain the calls together.

    3. Declare the ActionBar.TabListener to use for the tab by passing an instance of your implementation to setTabListener().
  5. Add each ActionBar.Tab to the Action Bar by calling addTab() on the ActionBar and passing the ActionBar.Tab.

For example, the following code combines steps 2 - 5 to create two tabs and add them to the Action Bar:

@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)));
}

All the behaviors that occur when a tab is selected must be defined by your ActionBar.TabListener callback methods. When a tab is selected, it receives a call to onTabSelected() and that's where you should add the appropriate fragment to the designated view in your layout, using add() with the provided FragmentTransaction. Likewise, when a tab is deselected (because another tab becomes selected), you should remove that fragment from the layout, using remove().

Caution: You must not call commit() for these transactions—the system calls it for you and it may throw an exception if you call it yourself. You also cannot add these fragment transactions to the back stack.

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 getSelectedNavigationIndex(). This returns the index position of the selected tab.

Caution: 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 Fragments developer guide.

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.

Here's a quick list of steps to enable drop-down navigation:

  1. Create a SpinnerAdapter that provides the list of selectable items for the drop-down and the layout to use when drawing each item in the list.
  2. Implement ActionBar.OnNavigationListener to define the behavior when the user selects an item from the list.
  3. Enable navigation mode for the Action Bar with setNavigationMode(). For example:
    ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
    

    Note: You should perform this during your activity's onCreate() method.

  4. Then, set the callback for the drop-down list with setListNavigationCallbacks(). For example:
    actionBar.setListNavigationCallbacks(mSpinnerAdapter, mNavigationCallback);
    

    This method takes your SpinnerAdapter and ActionBar.OnNavigationListener. More about these next.

That's the basic setup. However, implementing the SpinnerAdapter and 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 SpinnerAdapter is beyond the scope of this document (you should refer to the SpinnerAdapter class reference for more information). However, below is a simple example for a SpinnerAdapter and ActionBar.OnNavigationListener to get you started (click the title to reveal the sample).

Example SpinnerAdapter and OnNavigationListener

SpinnerAdapter is an adapter that provides data for a spinner widget, such as the drop-down list in the Action Bar. SpinnerAdapter is an interface that you can implement, but Android includes some useful implementations that you can extend, such as ArrayAdapter and SimpleCursorAdapter. For example, here's an easy way to create a SpinnerAdapter by using ArrayAdapter implementation, which uses a string array as the data source:

SpinnerAdapter mSpinnerAdapter = ArrayAdapter.createFromResource(this, R.array.action_list,
          android.R.layout.simple_spinner_dropdown_item);

The createFromResource() method takes three parameters: the application Context, the resource ID for the string array, and the layout to use for each list item.

A string array defined in a resource looks like this:

<?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>

The ArrayAdapter returned by createFromResource() is complete and ready for you to pass it to setListNavigationCallbacks() (in step 4 from above). Before you do, though, you need to create the OnNavigationListener.

Your implementation of 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: onNavigationItemSelected().

The onNavigationItemSelected() method receives the position of the item in the list and a unique item ID provided by the SpinnerAdapter.

Here's an example that instantiates an anonymous implementation of OnNavigationListener, which inserts a Fragment into the layout container identified by R.id.fragment_container:

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;
  }
};

This instance of OnNavigationListener is complete and you can now call setListNavigationCallbacks() (in step 4), passing the ArrayAdapter and this OnNavigationListener.

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 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.

Here's a look at the ListContentFragment class that defines each fragment in this example:

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;
    }
}

Styling the Action Bar

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.

For simple modifications to the ActionBar, you can use the following methods:

setBackgroundDrawable()
Sets a drawable to use as the Action Bar's background. The drawable should be a Nine-patch image, a shape, or a solid color, so the system can resize the drawable based on the size of the Action Bar (you should not use a fixed-size bitmap image).
setDisplayUseLogoEnabled()
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 android:logo 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.)

For more complex customizations, you can use Android's style and theme framework to restyle your Action Bar in several ways.

The Action Bar has two standard themes, "dark" and "light". The dark theme is applied with the default holographic theme, as specified by the Theme.Holo theme. If you want a white background with dark text, instead, you can apply the Theme.Holo.Light theme to the activity in the manifest file. For example:

<activity android:name=".ExampleActivity"
          android:theme="@android:style/Theme.Holo.Light" />

For more control, you can override either the Theme.Holo or 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:

android:actionBarTabStyle
Style for tabs in the Action Bar.
android:actionBarTabBarStyle
Style for the bar that appears below tabs in the Action Bar.
android:actionBarTabTextStyle
Style for the text in the tabs.
android:actionDropDownStyle
Style for the drop-down list used for the overflow menu and drop-down navigation.
android:actionButtonStyle
Style for the background image used for buttons in the Action Bar.

For example, here's a resource file that defines a custom theme for the Action Bar, based on the standard Theme.Holo theme:

<?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>

Note: 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 state list drawable. Also be certain that your theme declares a parent theme, from which it inherits all styles not explicitly declared in your theme.

You can apply your custom theme to the entire application or to individual activities in your manifest file, like this:

<application android:theme="@style/CustomActionBar"
             ... />

Additionally, if you want to create a custom theme for your activity that removes the Action Bar completely, use the following style attributes:

android:windowActionBar
Set this style property false to remove the Action Bar.
android:windowNoTitle
Set this style property true to also remove the traditional title bar.

For more information about using themes in your application, read Applying Styles and Themes.

↑ Go to top

← Back to User Interface