How to create ActionBar/Toolbar and Menu in Android

There are two kind of bar with control items in activity

  • ActionBar is action control bar or navigation bar you usually see at the top of an app, it usually has an app logo icon on the left, name of the current screen next to the logo, and other menu list on the right. To use actionbar, you don’t have to define an actionbar in the layout file which is handy but it deosn’t give you much flexibilities when you want to do some customizations in the actionbar, such as adding background image, animations, place the actionbar on the bottom instead on the top.
  • Toolbar does evertying you can do with ActionBar, and gives you the freedom to do customiztions that you can’t do easily with ActionBar.

You can use either old ActionBar (without any declarations in XML) or define android.support.v7.widget.Toolbar in activity layout and customize it look and events (more coding in this way).

ActionBar example

Let's look at ActionBar and it's parameters. Insert following lines in onCreate method and you'll get ActionBar with icon

ActionBar actionBar = getSupportActionBar();
actionBar.setLogo(R.drawable.ic_launcher);
actionBar.setDisplayUseLogoEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);

Toolbar example

ToolBar was introduced in Android Lollipop, API 21 release and is the successor of the ActionBar. It's a ViewGroup that can be placed anywhere in your XML layouts. ToolBar's appearance and behavior can be more easily customized than the ActionBar.

There are two ways to use Toolbar

  1. Use a Toolbar as an ActionBar when you want to use the existing ActionBar facilities (such as menu inflation and selection, ActionBarDrawerToggle, and so on) but want to have more control over its appearance.
  2. Use a standalone Toolbar when you want to use the pattern in your app for situations that an ActionBar would not support; for example, showing multiple toolbars on the screen, spanning only part of the width, and so on.

So, you should replace ActionBar with ToolBar if you want the flexibilities that comes with the Toolbar (adding background image, animations, place the actionbar on the bottom instead on the top and so on). Note that the ActionBar continues to work and if all you need is a static bar at the top that can host icons and a back button, then you can safely continue to use ActionBar.

To use Toolbar as an ActionBar, first ensure the AppCompat-v7 support library is added to your application build.gradle (Module:app) file

dependencies {
  ...
  compile 'com.android.support:appcompat-v7:23.1.0'
}

Second, let's disable the theme-provided ActionBar. The easiest way is to have your theme extend from Theme.AppCompat.NoActionBar (or the light variant) within the res/styles.xml file

<resources>
  <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
  </style>
<resources>

Now you need to add a Toolbar to your Activity layout file. Below I place the Toolbar at the top of a LinearLayout like the standard ActionBar

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
      android:id="@+id/toolbar"
      android:minHeight="?attr/actionBarSize"  
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      app:titleTextColor="@android:color/white"
      android:background="?attr/colorPrimary">
    </android.support.v7.widget.Toolbar>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello world!"/>
</LinearLayout>

Next, in your Activity or Fragment, set the Toolbar to act as the ActionBar by calling the setSupportActionBar(Toolbar) method

import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        toolbar.setTitle(R.string.myTitle);
        //toolbar.setSubtitle("Subtitle");

        setSupportActionBar(toolbar);

        toolbar.setNavigationIcon(R.drawable.ic_toolbar_arrow);
        toolbar.setNavigationOnClickListener(
            new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(this, "Toolbar", Toast.LENGTH_SHORT).show();
                }
            }
        );
    }
}

Adding items to ActionBar or Toolbar

Menus are typically created in resource files using XML but they are stored in the res/menu directory though they can also be created in code. To create a menu resource, use the &lt;menu&gt; element.

The &lt;item&gt; element defines each individual menu item and is enclosed in the &lt;menu&gt; element. A basic menu item looks as follows

<item 
    android:id="@+id/menu_email"
    android:title="@string/menu_email" 
    android:showAsAction="ifRoom"
    android:icon="@android:drawable/ic_dialog_email"
    />

The most common &lt;item&gt; attributes are the following

  • id, this is the standard resource identifier;
  • title, this indicates the text to display;
  • icon, this is a draw-able resource;
  • showAsAction, this controls how the menu item is shown;
  • enabled, this is enabled by default.

The showAsAction attribute controls how the menu item is shown. The options include the following:

  • ifRoom, this menu item should be included in the Action Bar if there's enough space;
  • withText, this indicates that both the title and the icon should be shown;
  • never, this indicates that the menu item should never be included in the Action Bar;
  • always, this indicates that the menu item should be always included in the Action Bar.

First, we will add a string resource to the strings.xml file for the menu title. Start by opening the /res/values/strings.xml file and add the following <string> element to the <resources> element <string name="menu_email">EMail</string>

Create a new file in the res/menu directory (right click on res - New - Android resource directory) and call it menu_main.xml.

Open the menu_main.xml file and add the following XML to define the menu

<?xml version="1.0" encoding="utf-8"?>

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

<item android:id="@+id/menu_email"
    android:title="@string/menu_email"
    app:showAsAction="never">
</item>
</menu>

With the menu now created, we just have to override the onCreateOptionsMenu() method in our activity to inflate the menu

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

Add the following method to the application to see a Toast when the EMail menu is selected

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.menu_email:
            Toast.makeText(this, "EMail", Toast.LENGTH_LONG).show();
            break;
        case R.id.menu_go:
            break;
        default:
            break;
    }
    return true;
}

Creating sub menus

Sub menus are created and accessed in almost exactly the same manner as other menu elements and can be placed in any of the provided menus, although they cannot be placed within other sub menus. To define a sub menu, include a <menu> element within an <item> element.

Here is the XML form this recipe with two sub menu items added

<?xml version="1.0" encoding="utf-8"?>

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

<item android:id="@+id/menu_email
    android:title="@string/menu_email"
    app:showAsAction="never">

    <menu>
        <item android:id="@+id/menu_sub1"
            android:title="Sub menu 1" />
        <item android:id="@+id/menu_sub2"
            android:title="Sub menu 2" />
    </menu>
</item>
</menu>

Grouping menu items

Another menu feature that Android supports is grouping menu items. Android provides several methods for groups, including the following

  • setGroupVisible() show or hide all items;
  • setGroupEnabled() enable or disable all items;
  • setGroupCheckable() set the checkable behavior.

Android will keep all grouped items with showAsAction="ifRoom" together. This means all items in the group with showAsAction="ifRoom" will be in the Action Bar or all items will be in the overflow.

To create a group, add the <item> menu elements to a <group> element. Here is an example using the menu XML from this recipe with two additional items in a group

<?xml version="1.0" encoding="utf-8"?>

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

<group android:id="@+id/group_topmost">
    <item android:id="@+id/menu_item1" 
        android:title="Item 1"
        app:showAsAction="ifRoom"/>
    <item android:id="@+id/menu_item2"
        android:title="Item 2"
        app:showAsAction="ifRoom"/>
</group>

<item android:id="@+id/menu_email"
    android:title="@string/menu_email"
    app:showAsAction="never"/>
</menu>

Useful links

comments powered by Disqus