page.title=Using the Action Bar parent.title=User Interface parent.link=index.html @jd:body

Quickview

In this document

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

Key classes

  1. {@link android.app.ActionBar}
  2. {@link android.view.Menu}

See also

  1. Creating Menus

The Action Bar is a widget for activities that replaces the traditional title bar at the top of an activity. By default, the Action Bar includes the application logo on the left side, followed by the activity title. The Action Bar offers several useful features for applications—especially those targeted to tablet devices. The Action Bar features include the ability to:

Figure 1. A screenshot of the Action Bar in the NotePad sample application, containing action items to save and delete the note.

Adding the Action Bar

To add the Action Bar to your activities, simply target your application for HONEYCOMB or later, using the {@code <uses-sdk>} element. That is, by setting either the {@code android:minSdkVersion} or {@code android:targetSdkVersion} to HONEYCOMB or later, each activity in your application will include the Action Bar when running on devices with HONEYCOMB or later. 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="Froyo" />
    <application ... >
        ...
    </application>
</manifest>

This also enables the "Holographic" theme for all your activities, which is the new default application theme for HONEYCOMB and later.

Note: In order for the Holographic theme to be applied based on the target platform version, the {@code <uses-sdk>} element must appear before the {@code <application>} element.

Hide the Action Bar

If you want to hide the Action Bar for a particular activity, set the activity theme to {@code android:style/Theme.NoTitleBar}. For example:

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

Adding Action Items

For each action item you want to add to the Action Bar, you must add a menu item to the activity's Options Menu and declare that the item be shown as an action.

Figure 2. A screenshot from an Action Bar with two action items.

You can specify a menu item to appear as an action item—if there is room for it—from the menu resource by declaring {@code android:showAsAction="ifRoom"} for the {@code <item>} element. This way, the item will display 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). From your application code, you can specify the item to appear as an action item 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}.

If your 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 a screenshot of an Action Bar with two action items that include text.

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

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 item in the Action Bar, your activity receives a call to {@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}, passing the item ID. (If you added the item from a fragment, then the respective {@link android.app.Fragment#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} method is called for that fragment.)

Note: Menu items that appear in the Overflow Menu (not as action items) also show an icon, so it's best if you provide an icon for every menu item.

You can also declare an item to always appear as an action item, but you should avoid doing so. Most of the time, there will be enough room for several action items and they will appear in the order you declare them. If you set items to always appear as action items (instead of if room), then they are added without discrimination and there is a risk that they will collide with other elements in the Action Bar, such as tabs or custom views.

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

Using the application icon as an action item

By default, the application icon appears in the Action Bar on the left side, but does nothing when tapped. To use the application icon as an action item when tapped, you simply need to add a condition to your {@link android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} method that performs an action when the {@link android.view.MenuItem} ID is {@code android.R.id.home}. This ID is delivered every time the user taps the application icon.

For example, here's an implementation of {@link android.app.Activity#onOptionsItemSelected 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);
            startActivity(intent);
            break;
    }
    return super.onOptionsItemSelected(item);
}

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

You can also use the application icon to provide "up" navigation. The way you handle the event when a user taps the icon is the same, but if the user experience for the event is to navigate up to the parent activity, then you should indicate this behavior by setting the Action Bar to "show home as up." You can do so by calling {@link android.app.ActionBar#setDisplayOptions setDisplayOptions()} on your activity's {@link android.app.ActionBar}, and passing the {@link android.app.ActionBar#DISPLAY_HOME_AS_UP} display option.

To get the {@link android.app.ActionBar}, call {@link android.app.Activity#getActionBar} from your {@link android.app.Activity} during {@link android.app.Activity#onCreate onCreate()} (but be sure you do so after you've called {@link android.app.Activity#setContentView setContentView()}).

For example, here's how you can change the Action Bar display mode to show the application icon as an "up" action:

@Override
protected void onStart() {
  super.onStart();
  ActionBar actionBar = this.getActionBar();
  actionBar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_HOME_AS_UP);
}

Caution: If your activity does not have an Action Bar (if you did not set the theme of your activity or application to the holographic or Action Bar theme), then {@link android.app.Activity#getActionBar} returns null.

Adding an Action View

Figure 4. An action view with a search widget.

An action view is a customized view you can specify for an item in your Options Menu, to display in the Action Bar when the item is included as an action item. For example, you can include a menu item for "Search", which appears and behaves as a normal menu item in the Overflow Menu, but, when set as an action item, it provides an action view that is a {@link android.widget.SearchView}, so the user can initiate a search directly from the Action Bar. Figure 4 shows an example of this, in which a menu item for search provides an action view using the {@link android.widget.SearchView} widget.

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

Now, when the menu item is displayed as an action item, it's action view appears instead of the item's traditional icon and/or text. Yet, if for some reason the item does not appear in the Action Bar, then it behaves like a normal menu item in the Overflow Menu and you must respond accordingly when the user taps it, from the {@link android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} callback.

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:

@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

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

To add tabs to the Action Bar:

  1. 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()}.

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

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

  2. 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 after you've called {@link android.app.Activity#setContentView setContentView()}).
  3. Call {@link android.app.ActionBar#setNavigationMode(int) setNavigationMode(NAVIGATION_MODE_TABS)} to enable tab mode for the {@link android.app.ActionBar}.
  4. Create each tab for the Action Bar:
    1. Create a new {@link android.app.ActionBar.Tab} by calling {@link android.app.ActionBar#newTab()} on the {@link android.app.ActionBar}.
    2. 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()}.

      Tip: These methods return the same {@link android.app.ActionBar.Tab} instance, so you can chain the calls together.

    3. 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()}.
  5. 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}.<>

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.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);

    // 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 {@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()}.

Note: You do not need to call {@link android.app.FragmentTransaction#commit} for these transactions. 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 {@link android.app.ActionBar#getSelectedNavigationItem()}. 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 what you must do to enable drop-down navigation:

  1. Create a {@link android.widget.SpinnerAdapter} that provides the list of selectable items for the list and the layout to use when drawing each item in the list.
  2. Implement {@link android.app.ActionBar.OnNavigationListener} to define the behavior when the user selects an item from the list.
  3. Turn on navigation mode for the Action Bar with {@link android.app.ActionBar#setNavigationMode setNavigationMode()}. For example:
    ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
    

    You should perform this during your activity's {@link android.app.Activity#onCreate onCreate()} method.

  4. Following that, set the callback for your drop-down list with {@link android.app.ActionBar#setListNavigationCallbacks setListNavigationCallbacks()}. For example:
    actionBar.setListNavigationCallbacks(mSpinnerAdapter, mNavigationCallback);
    

    This method takes your {@link android.widget.SpinnerAdapter} and {@link android.app.ActionBar.OnNavigationListener}. More about these next.

That's the basic setup. 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. Implementing various types of {@link android.widget.SpinnerAdapter} is beyond the scope of this document—you should refer to the class refrence for more information about implementing it or extending an existing implementation. However, below is a simple example for a {@link android.widget.SpinnerAdapter} and {@link android.app.ActionBar.OnNavigationListener} to get you started.

Example: simple SpinnerAdapter

{@link android.widget.SpinnerAdapter} is an interface that you can implement to provide content for the list and is where your implementation for the drop-down list can be heavily customized. 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} with {@link android.widget.ArrayAdapter}, using a string array from resources:

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

This is now ready to be given to {@link android.app.ActionBar#setListNavigationCallbacks setListNavigationCallbacks()}, in step 4 from above.

A string array defined as 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>

Example: simple OnNavigationListener

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: {@link android.app.ActionBar.OnNavigationListener#onNavigationItemSelected onNavigationItemSelected()}.

The {@link android.app.ActionBar.OnNavigationListener#onNavigationItemSelected onNavigationItemSelected()} method receives the position of the item in the list and an item ID provided by the {@link android.widget.SpinnerAdapter}.

Here's an example that instantiates an anonymous implementation of {@link android.app.ActionBar.OnNavigationListener}, which inserts a {@link android.app.Fragment} into the layout container identified by {@code 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 {@link android.app.ActionBar.OnNavigationListener} can be given to {@link android.app.ActionBar#setListNavigationCallbacks setListNavigationCallbacks()}, in step 4 from above.

In this example, the fragment added is given a tag that can uniquely identify the fragment. For this example, the {@code ListContentFragment} class used uses this tag as the text for a {@link android.widget.TextView} in the fragment's layout. Here's how it's done:

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