ActionBar

Basic ActionBar – Part 3

In the previous article we got tab-based navigation working. Tab-based navigation works well when you have two or three navigation options, but does not work as well when there are more. Dropdown-based navigation is better suited when we a slightly larger number number of navigation options, and in this article we’ll cover how to create dropdown-based navigation within our ActionBar.

An example of dropdown-based navigation can be found in Google Maps:

Dropdown-based Navigation
Dropdown-based Navigation

The navigation appears as a Spinner within the ActionBar, and the dropdown of the Spinner contains the navigation options. Fitting all of these options in to tab-based navigation would be extremely difficult.

To use dropdown navigation we first need to set the navigation mode of the ActionBar and remove the title text to allow more space for the spinner:

[java] actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
actionBar.setTitle( “” );
[/java]

Next we need to create a SpinnerAdapter:

[java] final List> data =
new ArrayList>();
Map map = new HashMap();
map.put( “title”, getString( R.string.frag1 ) );
map.put( “fragment”, Fragment.instantiate( this,
Fragment1.class.getName() ));
data.add( map );
map = new HashMap();
map.put( “title”, getString( R.string.frag2 ) );
map.put( “fragment”, Fragment.instantiate( this,
Fragment2.class.getName() ));
data.add( map );
SimpleAdapter adapter = new SimpleAdapter( this, data,
android.R.layout.simple_spinner_dropdown_item,
new String[] { “title” },
new int[] { android.R.id.text1 } );
[/java]

This creates a list of Map objects. Each map contains two entries: “title” which is the text that will be displayed in the spinner; and “fragment” which is the Fragment to display when that spinner item is selected. From this we create a SimpleAdapter instance which uses a standard Android Spinner dropdown layout (which can be seen here – don’t you just love open source?), and maps the “title” entry from each Map in the List to the single TextView widget which appears in the layout.

SimpleAdapter is a subclass of SpinnerAdapter and is a useful way of binding to static content. In a real-world app you will probably want to use a different kind of Adapter. I’m only using it here to keep things simple and easy to understand.

Now that we have our SpinnerAdapter we need to set this on the ActionBar with a OnNavigationListener to handle the navigation callback. i.e. This gets call when the user changes the selection:

[java] actionBar.setListNavigationCallbacks( adapter,
new OnNavigationListener()
{
@Override
public boolean onNavigationItemSelected(
int itemPosition,
long itemId )
{
Map map =
data.get( itemPosition );
Object o = map.get( “fragment” );
if( o instanceof Fragment )
{
FragmentTransaction tx =
getFragmentManager().beginTransaction();
tx.replace( android.R.id.content,
(Fragment )o );
tx.commit();
}
return true;
}
}
);
[/java]

The onNavigationItemSelected method will be called whenever the user selects an item from the Spinner dropdown. It gets the Fragment instance that we added to the data from which the SpinnerAdapter was created, and then replaces the Content area of our Activity with the appropriate Fragment.

If we run this we see the following:

Dropdown Dark
Dropdown Dark

This works, but the text is rather dark on the Spinner. The reason for this is the default theme that was created by ADT 20 new project wizard for Android 4.0 and later. Themeing and styling the ActionBar can be a little tricky and will be the subject of a future article. For now we’ll just change the theme to use standard Holo.Light. So we’ll change res/values-v14/styles.xml:

[xml]