Support free tutorials





Quick links

Using the Android Toolbar (ActionBar) - Tutorial

Lars Vogel

Version 12

30.09.2015

Using the toolbar in Android applications

This tutorial describes how to use the toolbar widget in your Android application. It is based on Android 6.0.


Table of Contents

1. Introduction to the toolbar
1.1. What is the toolbar (action bar)?
1.2. Example
1.3. Action bar on devices lower than API 21
2. Using the toolbar
2.1. Entries in the action bar (actions)
2.2. Creating actions
2.3. Reacting to action selection
2.4. Search an action in the action bar
2.5. Changing the menu
3. Customizing the toolbar
3.1. Changing the visibility of the toolbar bar
3.2. Assigning a Drawable
3.3. Dimming the navigation buttons
3.4. Using immersive full screen mode
3.5. Enabling the split toolbar
4. Contributing to the action bar with fragments
5. Making the toolbar context sensitive with the contextual action mode
6. Exercise: Using the contextual action mode
6.1. Target
6.2. Create menu resource in the res/menu folder
6.3. Adjust your coding
7. Making the action bar dynamic
7.1. Custom views in the action bar
7.2. Action view
8. Action provider
8.1. What is an action provider?
8.2. Example: usage of the ShareActionProvider
9. Navigation via the application icon
9.1. Application icon as home
9.2. Application icon as Up button
10. Other means of actionbar navigation
10.1. Actionbar navigation is deprecated
10.2. Tab navigation
10.3. Dropdown menu navigation
10.4. Evaluation
11. Exercise: ActionBar
11.1. Project
12. Exercise: Add a toolbar to your application
12.1. Add a refresh icon
12.2. Add a menu XML resource
12.3. Add a toolbar view to your activity layout
12.4. Run the application and test the toolbar
13. References
13.1. Create an image via Android studio
13.2. Creating a resource folder
13.3. Creating a resource file
13.4. Add a new menu XML resource
13.5. Remove the usage of the support library
14. About this website
15. Links and Literature
15.1. Android ActionBar Resources
15.2. vogella GmbH training and consulting support

1. Introduction to the toolbar

1.1. What is the toolbar (action bar)?

The toolbar bar (formerly known as action bar) is represented as of Android 5.0 via the Toolbar view group and can be placed into your layout file. It can display the activity title, icon, actions which can be triggered, additional views and other interactive items. It can also be used for navigation in your application.

Before Android 5.0 the location of the toolbar (actionbar) was hard code to the top of the activity.

The toolbar is enabled for devices which specify a target SDK of API version 11 or higher. It is possible to disable the toolbar via the used theme, but the default Android themes have it enabled.

Applications with a target SDK version less than API 11 use the options menu if such a button is present on the device. The option menu is displayed if the user presses the Option button. The toolbar bar is superior to the options menu, as the action bar is clearly visible, while the options menu is only shown on request. In case of the options menu, the user may not recognize that options are available in the application.

1.2. Example

The following screenshot shows the toolbar of the Google+ Android application with interactive items and a navigation bar. On top it also indicates that the user can open a navigation bar on the side of the application.

ActionBar Screenshot

1.3. Action bar on devices lower than API 21

The toolbar has been introduced in Android 5.0 (API 21). If you want to use the toolbar on devices with an earlier Android release you can use the downport provided by the appcompat-v7 support library. Add for this the latest version of com.android.support:appcompat to your Gradle build file, for example, at this point com.android.support:appcompat-v7:22.2.0. See the following link for setting up the library v7 in your project: Setting up the support library.

This section focuses on the description of using the toolbar bar without the support library. You can port your application to an lower API version using the support library.

2. Using the toolbar

2.1. Entries in the action bar (actions)

Entries in the toolbar are typically called actions. While it is possible to create entries in the action bar via code, it is typically defined in an XML resource file.

Each menu definition is contained in a separate file in the res/menu folder. The Android tooling automatically creates a reference to this file in the R file, so that the menu resource can be accessed.

2.2. Creating actions

An activity adds entries to the action bar in its onCreateOptionsMenu() method.

The showAsAction attribute allows you to define how the action is displayed. For example, the ifRoom attribute defines that the action is only displayed in the action bar if there is sufficient screen space available.

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/action_refresh"
        android:orderInCategory="100"
        android:showAsAction="always"
        android:icon="@drawable/ic_action_refresh"
        android:title="Refresh"/>
    <item
        android:id="@+id/action_settings"
        android:title="Settings">
    </item>

</menu> 

The MenuInflator class allows to inflate actions defined in an XML file and adds them to the action bar. MenuInflator can get accessed via the getMenuInflator() method from your activity. The following example code demonstrates the creation of actions.

@Override
  public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.mainmenu, menu);
    return true;
  } 

Tip

While you can define the actions also in your source code, it is good practice to do this via XML files, as this results in less boilerplate code.

2.3. Reacting to action selection

If an action is selected, the onOptionsItemSelected() method in the corresponding activity is called. It receives the selected action as parameter. Based on this information, you can decide what to do. The usage of this method is demonstrated in the following code snippet.

@Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    // action with ID action_refresh was selected
    case R.id.action_refresh:
      Toast.makeText(this, "Refresh selected", Toast.LENGTH_SHORT)
          .show();
      break;
    // action with ID action_settings was selected
    case R.id.action_settings:
      Toast.makeText(this, "Settings selected", Toast.LENGTH_SHORT)
          .show();
      break;
    default:
      break;
    }

    return true;
  } 

2.4. Search an action in the action bar

To search for a menu item in a menu you can use the findItem() method of the Menu class. This method allows to search by id.

2.5. Changing the menu

The onCreateOptionsMenu() method is only called once. If you want to change the menu later, you have to call the invalidateOptionsMenu() method. Afterwards this onCreateOptionsMenu() method is called again.

3. Customizing the toolbar

3.1. Changing the visibility of the toolbar bar

You can change the visibility of the toolbar at runtime. The following code demonstrates that.

ActionBar actionBar = getActionBar();
actionBar.hide();
// more stuff here...
actionBar.show(); 

You can also change the text which is displayed alongside the application icon at runtime. The following example shows that.

ActionBar actionBar = getActionBar();
actionBar.setSubtitle("mytest");
actionBar.setTitle("vogella.com"); 

3.2. Assigning a Drawable

You also add a Drawable to the action bar as background via the ActionBar.setBackgroundDrawable() method.

The toolbar scales the image. Therefore it is best practice to provide a scalable drawable , e.g., a 9-patch or XML drawable.

As of Android 4.2 the background of the action bar can also be animated via an AnimationDrawable.

3.3. Dimming the navigation buttons

You can also dim the software navigation button in your Android application to have more space available. If the user touches the button of the screen, the navigation button is automatically shown again.

Dimming the navigation buttons is demonstrated by the following code snippet.

getWindow().
  getDecorView().
  setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); 

The following screenshots show an application with and without the navigation buttons.

Application with action bar

Application with dimmed action bar

3.4. Using immersive full screen mode

As of Android 4.4 (API 19) you can put your application into full screen mode. The first time this happens the system displays the user the info that he can restore the system bars with a downward swipe along the region where the system bars normally appear.

For example the following method also to put an activity into full screen mode.

// This method hides the system bars and resize the content
  private void hideSystemUI() {
    getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
            | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
            // remove the following flag for version < API 19
            | View.SYSTEM_UI_FLAG_IMMERSIVE); 
  } 

3.5. Enabling the split toolbar

You can define that the toolbar should be automatically split by the system if not enough space is available.

You can activate this via the android:uiOptions="SplitActionBarWhenNarrow" parameter in the declaration of your application activity in the AndroidManifest.xml file.

Note

If this option is activated, Android has the option to split the toolbar. Whether to split is decided by the system at runtime.

4. Contributing to the action bar with fragments

Fragments can also contribute entries to the toolbar bar.

To do this, call setHasOptionsMenu(true) in the onCreate() method of the fragment. The Android framework calls in this case the onCreateOptionsMenu() method in the fragment class and adds its menu items to the ones added by the activity .

5. Making the toolbar context sensitive with the contextual action mode

A contextual action mode activates a temporary toolbar that overlays the application toolbar for the duration of a particular sub-task.

The contextual action mode is typically activated by selecting an item or by long clicking on it.

To implement this, call the startActionMode() method on a view or on your activity. This method gets an ActionMode.Callback object which is responsible for the life cycle of the contextual action bar.

You could also assign a context menu to a view via the registerForContextMenu(view) method. A context menu is also activated if the user "long presses" the view. The onCreateContextMenu() method is called every time a context menu is activated as the context menu is discarded after its usage. You should prefer the contextual action mode over the usage of context menus.

6. Exercise: Using the contextual action mode

6.1. Target

In this exercise you add a contextual action mode to one of your existing applications.

6.2. Create menu resource in the res/menu folder

For this, create a new menu XML resource with the actionmode.xml file name. See ??? for details.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/action_share"
        android:title="Share it"
        >
    </item>
</menu> 

6.3. Adjust your coding

Extend your fragment interface.

public class MyListFragment extends Fragment {

    public void goToActionMode(RssItem item) {
        listener.goToActionMode(item);
    }

    public interface OnItemSelectedListener {

      public void onRssItemSelected(String link);

        public void goToActionMode(RssItem item);
    } 

Change your activity to implement this new method and also the ActionMode.Callback callback as demonstrated in the following example code.

package com.example.android.rssreader;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;
import android.widget.Toolbar;

import com.example.android.rssfeedlibrary.RssItem;

public class RssfeedActivity extends Activity 
  implements MyListFragment.OnItemSelectedListener, 
        ActionMode.Callback {

    private RssItem selectedRssItem;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar tb = (Toolbar) findViewById(R.id.toolbar);
        setActionBar(tb);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        Toolbar tb = (Toolbar) findViewById(R.id.toolbar);
        tb.inflateMenu(R.menu.mainmenu);
        tb.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        return onOptionsItemSelected(item);
                    }
                });

        return true;
    }

    //NEW
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_refresh:
              MyListFragment fragment = (MyListFragment) getFragmentManager()
              .findFragmentById(R.id.listFragment);
              fragment.updateListContent();
                break;
            case R.id.action_settings:
                Intent intent = new Intent(this, MyPreferences.class);
                startActivity(intent);
                Toast.makeText(this, "Action Settings selected", Toast.LENGTH_SHORT)
                        .show();
                break;

            default:
                break;
        }

        return true;
    }


    @Override
    public void onRssItemSelected(String link) {
        if (getResources().getBoolean(R.bool.twoPaneMode)) {
            DetailFragment fragment = (DetailFragment) getFragmentManager()
                    .findFragmentById(R.id.detailFragment);
            fragment.setText(link);
        } else {
            Intent intent = new Intent(getApplicationContext(),
                    DetailActivity.class);
            intent.putExtra(DetailActivity.EXTRA_URL, link);
            startActivity(intent);
        }
    }

    @Override
    public void showContextMenu(RssItem item) {
        this.selectedRssItem = item;
        startActionMode(this);
    }

    @Override
    public void goToActionMode(RssItem item) {
        this.selectedRssItem = item;
        startActionMode(this);
    }


    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        MenuInflater inflater = mode.getMenuInflater();
        inflater.inflate(R.menu.actionmode, menu);
        return true;
    }

    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        return false;
    }

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.putExtra(Intent.EXTRA_TEXT, "I found this interesting link" + 
            selectedRssItem.getLink());
        intent.setType("text/plain");
        startActivity(intent);
        mode.finish(); // Action picked, so close the CAB
        selectedRssItem = null;
        return true;
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {

    }
} 

In your adapter implement a LongClickListener which triggers the contextual action mode.

package com.example.android.rssreader;

import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.example.android.rssfeedlibrary.RssItem;

import java.util.List;
import java.util.Random;

public class RssItemAdapter
        extends RecyclerView.Adapter<RssItemAdapter.ViewHolder> {

    private List<RssItem> rssItems;
    private MyListFragment myListFragment;

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v= null;
        v = LayoutInflater.
                from(parent.getContext()).
                inflate(R.layout.rowlayout, parent, false);
        return new ViewHolder(v);
    }


    public static class ViewHolder extends RecyclerView.ViewHolder {
        public View mainLayout;
        public TextView txtHeader;
        public TextView txtFooter;
        public ImageView imageView;

        public ViewHolder(View v) {
            super(v);
            mainLayout = v;
            txtHeader = (TextView) v.findViewById(R.id.rsstitle);
            txtFooter = (TextView) v.findViewById(R.id.rssurl);
            imageView = (ImageView) v.findViewById(R.id.icon);
        }
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
        final RssItem rssItem = rssItems.get(position);
        holder.txtHeader.setText(rssItem.getTitle());
        holder.txtFooter.setText(rssItem.getLink());
        holder.mainLayout.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                myListFragment.updateDetail(rssItem.getLink());
            }
        });
        holder.mainLayout.setOnLongClickListener(new View.OnLongClickListener() {

            @Override
            public boolean onLongClick(View v) {
                myListFragment.goToActionMode(rssItem);
                return true;
            }

        });
    }

    @Override
    public int getItemCount() {
        return rssItems.size();
    }


    public RssItemAdapter(List<RssItem> rssItems, MyListFragment myListFragment) {
        this.rssItems = rssItems;
        this.myListFragment = myListFragment;
    }


} 

7. Making the action bar dynamic

7.1. Custom views in the action bar

You can also add a custom view to the action bar, for example, a button or a text field.

For this you use the setCustomView method of the ActionView class. You also have to enable the display of custom views via the setDisplayOptions() method by passing in the ActionBar.DISPLAY_SHOW_CUSTOM flag.

For example, you can define a layout file which contains a EditText element.

<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/searchfield"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:inputType="textFilter" >

</EditText> 

This layout can be assigned in an activity to the action bar via the following code. The example code also attaches a listener to the custom view.

package com.vogella.android.actionbar.customviews;

import android.app.ActionBar;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;

public class MainActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ActionBar actionBar = getActionBar();
    // add the custom view to the action bar
    actionBar.setCustomView(R.layout.actionbar_view);
    EditText search = (EditText) actionBar.getCustomView().findViewById(R.id.searchfield);
    search.setOnEditorActionListener(new OnEditorActionListener() {

      @Override
      public boolean onEditorAction(TextView v, int actionId,
          KeyEvent event) {
        Toast.makeText(MainActivity.this, "Search triggered",
            Toast.LENGTH_LONG).show();
        return false;
      }
    });
    actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM
        | ActionBar.DISPLAY_SHOW_HOME);
  }

} 

7.2. Action view

An action view is a widget that appears in the action bar as a substitute for an action item's button. You can, for example, use this feature to replace an action item with a ProgressBar view. An action view for an action can be defined via the android:actionLayout or android:actionViewClass attribute to specify either a layout resource or widget class to use.

This replacement is depicted in the following screenshots.

Before activating the ActionView

ActionViews running

The following activity replaces the icon at runtime with an action view which contains a ProgressBar view.

package com.vogella.android.actionbar.progress;

import android.app.ActionBar;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends Activity {

  private MenuItem menuItem;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ActionBar actionBar = getActionBar();
    actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME
        | ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_CUSTOM);
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.menu_load:
      menuItem = item;
      menuItem.setActionView(R.layout.progressbar);
      menuItem.expandActionView();
      TestTask task = new TestTask();
      task.execute("test");
      break;
    default:
      break;
    }
    return true;
  }

  private class TestTask extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {
      // Simulate something long running
      try {
        Thread.sleep(2000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      return null;
    }

    @Override
    protected void onPostExecute(String result) {
      menuItem.collapseActionView();
      menuItem.setActionView(null);
    }
  };
} 

The following code shows the layout used for the action view.

<?xml version="1.0" encoding="utf-8"?>
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/progressBar2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

</ProgressBar> 

The following code shows the XML files for the menu.

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/menu_settings"
        android:orderInCategory="100"
        android:showAsAction="always"
        android:title="Settings"
        />

    <item
        android:id="@+id/menu_load"
        android:icon="@drawable/navigation_refresh"
        android:orderInCategory="200"
        android:showAsAction="always"
        android:title="Load"/>

</menu> 

8. Action provider

8.1. What is an action provider?

An action provider defines rich menu interaction in a single component. It can generate action views, which are used in the action bar, dynamically populate sub-menus of an action and handle default action invocations.

The base class for an action provider is the ActionProvider class.

Currently the Android platform provides two action providers: the MediaRouteActionProvider and the ShareActionProvider.

8.2. Example: usage of the ShareActionProvider

The following demonstrates the usage of the ShareActionProvider. This action provider allows you to grab selected content from applications which have registered the Intent.ACTION_SEND intent.

To use ShareActionProvider, you have to define a special menu entry for it and assign an intent which contains the sharing data to it.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

   <item android:id="@+id/menu_share"
          android:title="Share"
          android:showAsAction="ifRoom"
          android:actionProviderClass="android.widget.ShareActionProvider" />
    <item
        android:id="@+id/item1"
        android:showAsAction="ifRoom"
        android:title="More entries...">
    </item>

</menu> 

@Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);

    // Get the ActionProvider for later usage
    provider = (ShareActionProvider) menu.findItem(R.id.menu_share)
        .getActionProvider();
    return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.menu_share:
      doShare();
      break;
    default:
      break;
    }
    return true;  
  }

  public void doShare() {
    // populate the share intent with data
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType("text/plain");
    intent.putExtra(Intent.EXTRA_TEXT, "This is a message for you");
    provider.setShareIntent(intent);
  } 

9. Navigation via the application icon

9.1. Application icon as home

The action bar shows an icon of your application. This is called the home icon. You can assign an action to this icon. The recommendation is to return to the main activity in your program if the user selects this icon.

If the action is selected, the onOptionsItemSelected() method is called with an action which has the android.R.id.home ID.

Before Android 4.1, you had to use the android.R.id.home ID in the onOptionMenuItemSelected() method and enable the selection of the home button. This is demonstrated by the following code in which the SecondActivity activity defines the MainActivity as home.

package com.vogella.android.actionbar.homebutton;

import android.os.Bundle;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuItem;

public class SecondActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // enable the home button
    ActionBar actionBar = getActionBar();
    actionBar.setHomeButtonEnabled(true);
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case android.R.id.home:
      Intent intent = new Intent(this, MainActivity.class);
      intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
      startActivity(intent);
      break;
      // Something else
    case R.id.action_settings:
      intent = new Intent(this, ThirdActivity.class);
      startActivity(intent);
    default:
      break;
    }
    return super.onOptionsItemSelected(item);
  }

} 

Tip

As of Android 4.1 you can simply set the parentActivityName in the AndroidManifest.xml file pointing to the parent activity.

<activity
  android:name="SecondActivity"
  android:label="@string/app_name"
  android:parentActivityName="MainActivity" >
</activity> 

9.2. Application icon as Up button

You can use the application icon also as Up button, e.g., to go to the parent activity of the current activity. The back button on the device always returns to the previous activity.

Both can be different, for example, if the user started the option to write an email from the home screen, the back button will return the user to the home screen while the Up button would return the user to the activity which shows an overview of all emails.

To enable the Up display, you can use the following code snippet in your activity.

actionBar.setDisplayUseLogoEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(true); 

Note

This snippet only enables the Up display on your home icon. You need to implement the correct behavior in your activity in the onOptionsItemSelected() method. The corresponding action still has the android.R.id.home ID.

Warning

The difference between Up and the Back button can be confusing for the end user. If you decide to implement Up, in your application, it is recommended to perform some end user testing to see if the Up implementation is intuitive for them or not.

10. Other means of actionbar navigation

10.1. Actionbar navigation is deprecated

As of Android 5.0 the navigation options described in this chapter are deprecated and should not be used anymore in new applications.

10.2. Tab navigation

Fragments can also be used in combination with the action bar for navigation. For this your main activity needs to implement a TabListener, which is responsible for moving between the tabs.

To add a new tab to the action bar, use the newTab() method.

The following code shows such an activity. It uses dummy activities to demonstrate the switch.

package com.vogella.android.actionbar.tabs;

import android.app.ActionBar;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class MainActivity extends FragmentActivity implements
    ActionBar.TabListener {

  
/** * The serialization (saved instance state) Bundle key representing the * current tab position. */
private static final String STATE_SELECTED_NAVIGATION_ITEM = "selected_navigation_item"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Set up the action bar to show tabs. final ActionBar actionBar = getActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); // for each of the sections in the app, add a tab to the action bar. actionBar.addTab(actionBar.newTab().setText(R.string.title_section1) .setTabListener(this)); actionBar.addTab(actionBar.newTab().setText(R.string.title_section2) .setTabListener(this)); actionBar.addTab(actionBar.newTab().setText(R.string.title_section3) .setTabListener(this)); } @Override public void onRestoreInstanceState(Bundle savedInstanceState) { // Restore the previously serialized current tab position. if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) { getActionBar().setSelectedNavigationItem(savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM)); } } @Override public void onSaveInstanceState(Bundle outState) { // Serialize the current tab position. outState.putInt(STATE_SELECTED_NAVIGATION_ITEM, getActionBar() .getSelectedNavigationIndex()); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } @Override public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { // When the given tab is selected, show the tab contents in the // container view. Fragment fragment = new DummySectionFragment(); Bundle args = new Bundle(); args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, tab.getPosition() + 1); fragment.setArguments(args); getFragmentManager().beginTransaction() .replace(R.id.container, fragment).commit(); } @Override public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { } @Override public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { }
/** * A dummy fragment representing a section of the app */
public static class DummySectionFragment extends Fragment { public static final String ARG_SECTION_NUMBER = "placeholder_text"; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { TextView textView = new TextView(getActivity()); textView.setGravity(Gravity.CENTER); textView.setText(Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER))); return textView; } } }

10.3. Dropdown menu navigation

You can also use a spinner in the action bar. The following code demonstrates such an implementation.

package com.vogella.android.actionbar.spinner;

import android.app.ActionBar;
import android.app.Fragment;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class MainActivity extends FragmentActivity implements
    ActionBar.OnNavigationListener {

  
/** * The serialization (saved instance state) Bundle key representing the * current dropdown position. */
private static final String STATE_SELECTED_NAVIGATION_ITEM = "selected_navigation_item"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Set up the action bar to show a dropdown list. final ActionBar actionBar = getActionBar(); actionBar.setDisplayShowTitleEnabled(false); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); final String[] dropdownValues = getResources().getStringArray(R.array.dropdown); // Specify a SpinnerAdapter to populate the dropdown list. ArrayAdapter<String> adapter = new ArrayAdapter<String>(actionBar.getThemedContext(), android.R.layout.simple_spinner_item, android.R.id.text1, dropdownValues); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); // Set up the dropdown list navigation in the action bar. actionBar.setListNavigationCallbacks(adapter, this); // use getActionBar().getThemedContext() to ensure // that the text color is always appropriate for the action bar // background rather than the activity background. } @Override public void onRestoreInstanceState(Bundle savedInstanceState) { // Restore the previously serialized current dropdown position. if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) { getActionBar(). setSelectedNavigationItem(savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM)); } } @Override public void onSaveInstanceState(Bundle outState) { // Serialize the current dropdown position. outState.putInt(STATE_SELECTED_NAVIGATION_ITEM, getActionBar() .getSelectedNavigationIndex()); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } @Override public boolean onNavigationItemSelected(int position, long id) { // When the given dropdown item is selected, show its contents in the // container view. Fragment fragment = new DummySectionFragment(); Bundle args = new Bundle(); args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1); fragment.setArguments(args); getFragmentManager().beginTransaction() .replace(R.id.container, fragment).commit(); return true; }
/** * A dummy fragment */
public static class DummySectionFragment extends Fragment { public static final String ARG_SECTION_NUMBER = "placeholder_text"; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { TextView textView = new TextView(getActivity()); textView.setGravity(Gravity.CENTER); textView.setText(Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER))); return textView; } } }

10.4. Evaluation

While the navigation drawer is relatively new compared to the other options, it is pretty popular among users and Android applications. If in doubt which options to select, consider using the navigation drawer.

11. Exercise: ActionBar

11.1. Project

This chapter will demonstrate how to create actions in the action bar and react to the selection of the user.

It is based on the fragment tutorial which can be found under Android fragments tutorial. If you have already created this project, you can continue to reuse it. If not, the following describes the required setup to continue with this tutorial.

12. Exercise: Add a toolbar to your application

12.1. Add a refresh icon

Continue to use the RSS Reader project. Create a new icon called ic_refresh. See Section 13.1, “Create an image via Android studio” for details how to create an image.

12.2. Add a menu XML resource

Create a new XML resource for your menu called mainmenu.xml. See ??? for details how to do it.

Add two entries so that the resulting XML file, similar to the following listing. You may have to type these entries, as the time of this writing Android Studio offers no code completion of menus.

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/action_refresh"
        android:orderInCategory="100"
        android:showAsAction="ifRoom"
        android:icon="@drawable/ic_action_refresh"
        android:title="Refresh"/>
    <item
        android:id="@+id/action_settings"
        android:title="Settings"
        android:showAsAction="never"
        >
    </item>

</menu> 

12.3. Add a toolbar view to your activity layout

Change the layout file of your RssfeedActivity activity to also contain a toolbar entry.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:orientation="horizontal"
        android:layout_weight="1"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        >

        <fragment
            android:id="@+id/listFragment"
            class="com.example.android.rssreader.MyListFragment"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            tools:layout="@layout/fragment_rsslist_overview"></fragment>

        <fragment
            android:id="@+id/detailFragment"
            class="com.example.android.rssreader.DetailFragment"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="2"
            tools:layout="@layout/fragment_rssitem_detail" />

    </LinearLayout>

    <Toolbar
        android:id="@+id/toolbar"
        style="@style/ToolbarStyling"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentStart="true">

    </Toolbar>
</LinearLayout> 

Change your RssfeedActivity class to the following code, to configure the toolbar view.

package com.example.android.rssreader;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class RssfeedActivity extends Activity implements MyListFragment.OnItemSelectedListener {
  // Unchanged
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_rssfeed);
    Toolbar tb = (Toolbar) findViewById(R.id.toolbar);
      // ensure toolbar acts as action bar
    setActionBar(tb);
  }
  
  //New
  @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        Toolbar tb = (Toolbar) findViewById(R.id.toolbar);
        tb.inflateMenu(R.menu.mainmenu);
        tb.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        return onOptionsItemSelected(item);
                    }
                });
        return true;
    }
  
  //New
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.action_refresh:
      Toast.makeText(this, "Action refresh selected", Toast.LENGTH_SHORT)
          .show();
      break;
    case R.id.action_settings:
      Toast.makeText(this, "Action Settings selected", Toast.LENGTH_SHORT)
          .show();
      break;

    default:
      break;
    }

    return true;
  }

  // Other methods which this class implements
} 

12.4. Run the application and test the toolbar

Run your application and validate that you can select both of your actions. Ensure that the correct info message is displayed if you select the different entries.

Social App running

If your device or emulator has an Option menu button, you will not see the overflow menu. Press the Option key to see your second action.

13. References

13.1. Create an image via Android studio

See Creating an image asset to learn how to create an image asset with Android Studio.

13.2. Creating a resource folder

See Creating a new resource folder to learn how to a new resource file with Android Studio.

13.3. Creating a resource file

See Creating a new resource file to learn how to a new resource file with Android Studio.

13.4. Add a new menu XML resource

See Add a new menu XML resource to learn how to a new XML menu resource with Android Studio.

13.5. Remove the usage of the support library

See Android support library how to remove the usage of the support library.

14. About this website

15. Links and Literature

15.1. Android ActionBar Resources

Android Design Page

Android ActionBar Sherlock

15.2. vogella GmbH training and consulting support

TRAINING SERVICE & SUPPORT
The vogella company provides comprehensive training and education services from experts in the areas of Eclipse RCP, Android, Git, Java, Gradle and Spring. We offer both public and inhouse training. Whichever course you decide to take, you are guaranteed to experience what many before you refer to as “The best IT class I have ever attended”. The vogella company offers expert consulting services, development support and coaching. Our customers range from Fortune 100 corporations to individual developers.