Android Adventures - Menus - The Toolbar
Written by Mike James   
Tuesday, 05 May 2015
Article Index
Android Adventures - Menus - The Toolbar
Action Bar
Responding to menu events
Controlling the Action Bar

 

The Toolbar

If you start a new basic Activity project called MenuSample then you will discover that it automatically creates a main_menu resource file and the code needed to display it as a tool bar. Previously it would have added an App Bar but Google recommends that we change to using the Toolbar widget. The basic Activity template uses the support library to make it possible in earlier versions of Android. In this case the Activity has to derive from the AppCompatActivity class:

public class MainActivity extends AppCompatActivity {

and we need the imports:

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

The Toolbar is defined in activity_main.xml as a custom widget:

<android.support.design.widget.AppBarLayout
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:theme="@style/AppTheme.AppBarOverlay"> 
 <android.support.v7.widget.Toolbar
  android:id="@+id/toolbar"
  android:layout_width="match_parent"
  android:layout_height="?attr/actionBarSize"
  android:background="?attr/colorPrimary"
  app:popupTheme="@style/AppTheme.PopupOverlay"
  style="@style/AppTheme" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />

...

Notice that the Toolbar's style is set to AppTheme. This is important as the style selected changes the way the Toolbar is displayed and can stop it from displaying altogether. Also notice the tag

<include layout="@layout/content_main" />

This loads the layout that you design in content_main.xml. That is, as explained in earlier chapters the layout files are split into two parts - activity_main.xml which defines the layout that should be common to all Android apps and content_main.xml which is used for the layout specific to your app. The two files are automatically merged together when activity_main.xml is loaded. 

When the Activity loads onCreate runs and inflates the layout in activity_main.xml and the included content_main.xml. This is enough for the toolbar to display but for it to be used as a toolbar by the system we need to add:

Toolbar toolbar =
          (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

All of this code is generated for you automatically and you will find it in the MainActivity.java file in onCreate:

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

Now if you run the app you will see the familiar Hello world message and the default toolbar:

actionmenu1a

 

In fact it is so familiar you may not even have realized that it is a menu. The toolbar  has the name of the app to the left and a three dot icon to the right. If you select the three dot icon the Settings menu item appears:

actionmenu2a

 

If you take a look at the menu_main.xml file you can see the definition of this menu:

<menu xmlns:android=
   "http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 xmlns:tools="http://schemas.android.com/tools"
 tools:context=
   "com.example.mikejames.myapplication.MainActivity">
<item
  android:id="@+id/action_settings"
  android:orderInCategory="100"
  android:title="Settings"
  app:showAsAction="never" />
</menu>

You can see that this defines a single menu with a single item with the title "Settings".

There are some new attributes being used in the item tag. The showAsAction attribute is important for the way the action bar works.

By default the system places menu items into the overflow area that is only revealed when the user selects the three dot icon or more generally the action overflow icon. However for items that you would like to give the user a more direct access to you can set the showAsAction attribute.

This can be set to any of the following:

  • ifRoom - show if there is room
  • never - never show in the visible area
  • withText - show with text
  • always - always show even if it means overlapping other items
  • collapseActionView - show a collapsed view of the item.

As you can see the Settings item in the default action bar is set to never show. 

The showAsAction attribute works with the orderInCategory attribute to determine the order that items are shown. 

To see this in action let's add another item. Add to the end of the menu_main.xml file before the final </menu>  tag: 

<item android:id="@+id/action_send"
 android:title="Send"
 app:showAsAction="ifRoom" />

Now if you run the app you will see:

 

actionmenu3a

 

This works and the new item will be displayed as long as there is room - if there isn't it will appear when the user selects the three dots icon.

It is usual to show toolbar items as icons so change the item tag to read:

<item android:id="@+id/action_send"
 android:title="Send"
 app:showAsAction="ifRoom"
 android:icon="@android:drawable/ic_menu_send"/>

where we are using one of the many supplied icons.

 

actionmenu4a

 

You can carry on adding menu items to the action bar and generally customizing how they display given different screen widths - the general idea is the same for all menus.

Creating The Toolbar 

So far we have just looked at the menu_main.xml file and the XML specification of the action bar menu. There is also some code generated to actually create the menu displayed in the Toolbar.  

The Activity will fire a CreateOptionsMenu event when it is ready to display the toolbar recall the toolbar used to be called the actionbar and before that the Options Menu.

All the onCreateOptionsMenu event handler has to do is inflate the XML file that defines the menu:

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

 

The onCreateOptionsMenu is called once when the Activity starts. Before Android 3 it was called each time the menu was displayed on the screen but later the actionbar/toolbar is always on display. How to change the toolbar is discussed later.

All the event handler has to do is use the appropriate inflater object to create the menu from the resource file. The new View hierarchy of menu and item objects is added to the menu object passed to the event handler. This is important because it means that your new menu items are added to any that are already there. This allows other Activitys and Fragments to add items to a common toolbar. 

Where's My Action Bar?

If you try any of this out then there is a chance that you will do everything correct and yet your action bar will not show. 

There are only two common reasons for this.

The first is that you are targeting and using an early version of Android which doesn't support the action bar. This is unlikely especially if you are using the support library. 

The second, and this is much more common, is that you are using a theme that doesn't support the action bar or doesn't support the type of action bar you are using. 

The solution is easy.

For Android 5 or later or the support library select one of the AppCompat themes if you want to make use of the new features introduced with Android 5. 

However if you select a new theme in the designer then it isn't automatically passed on to the app when you run it. To change the overall theme for the app you have to edit the styles.xml file in the res/values folder. Change the parent= to the theme you want to use - e.g. 

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

As always Android Studio generates the correct xml for the styles that work with the Toolbar.



Last Updated ( Tuesday, 14 March 2017 )