Menus, Menus, Menus – Android with Xamarin

By | January 28, 2014

Building on the previous example on this article I show the different type of menus available to Android apps and how to use them.

You can download the working example here.

Options Menu

Figure 1. Android menu button

Figure 1. Android menu button

The options menu is available in the current activity. It is activated by pressing the menu button on the phone as shown in the figure 1.

menuresource

Figure 2. The menu .xml file must be located in the menu folder under Resources.

The menu can be built in code but as recommended I have defined the menu as a resource file. The file is an .xml file and must be located in a menu folder under Resources as shown in figure 2.

You can see the detailed specifications for the menu .xml file here.

In this example this is what the menu .xml file looks like:

<?xml version=“1.0” encoding=“UTF-8” ?>
<menu xmlns:android=“http://schemas.android.com/apk/res/android”
android:id=“@+id/mainMenu”
android:background=“@color/light_gray”>
  <item android:id=“@+id/add”
        android:icon=“@drawable/ic_action_new”
        android:title=“New”>
  </item>
  <item android:id=“@+id/phone”
        android:title=“Phone”>
        <menu android:id=“@+id/submenu”>
          <item android:id=“@+id/call”
                android:icon=“@drawable/ic_action_call”
                android:title=“Call”/>
        </menu>
  </item>
  <item android:id=“@+id/refresh”
        android:icon=“@drawable/ic_action_refresh”
        android:title=“Refresh”/>
</menu>

A few things I would like to mention; I define the background color for the menu by adding the android:background attribute. As you can see I also add icons to each of the menu items using the android:icon attribute. As mentioned in the previous article the icons are located under the Resources folder based on their resolutions.

The other thing I would like to mention is how you can create a sub-menu for a specific item of the menu. All you need to do is add a <menu> tag under the item as shown in the xml code above. I added a sub-menu for the <item> with the id @+id/phone

Implementing the Options Menu

The first step of the implementation of this menu is overriding the OnCreateOptionsMenu method of the activity. This method is called as the activity starts.

    public override bool OnCreateOptionsMenu(IMenu menu)
    {
      base.OnCreateOptionsMenu (menu);

      MenuInflater inflater = this.MenuInflater;

      inflater.Inflate (Resource.Menu.mainmenu, menu);

      return true;
    }

As you see in the code above the loading of the menu is pretty straight forward. The Resource.Menu.mainmenu is the name of the .xml menu file.

The next setup is implementing the method that will fire when one of the options of the menu is clicked. That is done by overriding the OnOptionsItemSelected.

    public override bool OnOptionsItemSelected (IMenuItem item)
    {
      base.OnOptionsItemSelected (item);

      switch (item.ItemId)
      {
      case Resource.Id.add:
        break;
      case Resource.Id.call:
        {
          Intent intent = new Intent (Intent.ActionDial);
          StartActivity (intent);
          break;
        }
      default:
        break;
      }

      return true;
    }

Again quite simple to implement. When this method is called the item object is passed. The item object is a representation of the item of the menu defined in the menu .xml file.

That said I use the item id in the switch to find out which option of the menu was clicked so I can do the corresponding work. Just would like to mention specifically what happens when the option with the id Resource.Id.call is called. I’m using intents to bring up the dialer in the phone. It looks like the pictures below.

The Popup Menu

Overflowbutton

Figure 6. The overflow button

For this example I wanted a menu to open when I clicked the overflow image button in the action bar.

First got a reference to that button and hooked a method to the click event with the code below added to the onCreate of the activity.

overflowButton = this.Window.FindViewById<ImageButton> (Resource.Id.imageButton1);
overflowButton.Click += new EventHandler (OnOverflowClick);

Next I implemented the OnOverflowClick. Here I added the code to inflate and show the popup menu. I also added a hook to the MenuItemClick event so I can control the options that are clicked.

    public void OnOverflowClick(object sender, EventArgs args)
{
PopupMenu popupMenu = new PopupMenu (thisthis.overflowButton);

popupMenu.MenuInflater.Inflate (Resource.Menu.mainmenu, popupMenu.Menu);
popupMenu.Show ();

popupMenu.MenuItemClick += new EventHandler<PopupMenu.MenuItemClickEventArgs>(OnPopupMenuItemSelected);
}

Lastly I implemented the OnPopupMenuItemSelected to control the options clicked. For the popup menu I just used the same mainmenu .xml file I used for the options menu. This is what the OnPopupMenuItemSelected looks like. In the code above you can see that I’m attaching the popup menu to the instance of the overflow image button when I inflate the menu.

    public void OnPopupMenuItemSelected(object sender, PopupMenu.MenuItemClickEventArgs args)
    {
      switch (args.Item.ItemId)
      {
      case Resource.Id.add:
        break;
      case Resource.Id.call:
        {
          Intent intent = new Intent (Intent.ActionDial);
          StartActivity (intent);
          break;
        }
      default:
        break;
      }
    }

This is what the menu looks like when you click the overflow button.

 

Figure 7. Popup menu

Figure 7. Popup menu

The Context Menu

To demonstrate how to use the context menu I added a TextView to the LinearLayout in order to attach the menu to it. Basically when you click the text box the context menu pops open. Once you click an option of the menu a text message is written in the text box.

Now moving to the implementation. For the context menu I created a new menu .xml file called contextmenu. This is what it looks like:

 

<?xml version=“1.0” encoding=“UTF-8” ?>
<menu xmlns:android=“http://schemas.android.com/apk/res/android”
android:id=“@+id/contextMenu”
android:background=“@color/light_gray”>
  <item android:id=“@+id/add”
        android:title=“New”>
  </item>
  <item android:id=“@+id/refresh”
        android:title=“Refresh”/>
</menu>

The first step in setting up a context menu is to register a view with the context menu. I do that in the onCreate event of the activity with the following code:

      textView = FindViewById<TextView> (Resource.Id.txClickMe);
  RegisterForContextMenu (textView);

First I get a reference to the TextView and then use the reference with the call to the RegisterForContextMenu.

Next we need a way to show the menu. I decided that I would show the menu when clicking the TextView so I hooked a method to the TexView click event:

this.textView.Click += new EventHandler (OnTextViewClick);

In the OnTextViewClick I wrote the code that shows the menu. As simple as:

    public void OnTextViewClick (object sender, EventArgs args)
  {
    ((TextView)sender).ShowContextMenu ();
  }

Now when you click the TexView this method gets called and when ShowContextMenu is called the sytem will fire the OnCreateContextMenu. I did override this method and added the necessary code to inflate the menu.

    public override void OnCreateContextMenu (IContextMenu menu, View v, IContextMenuContextMenuInfo menuInfo)
 {
    base.OnCreateContextMenu (menu, v, menuInfo);

    MenuInflater menuInflater = new MenuInflater (this);
    menuInflater.Inflate (Resource.Menu.contextmenu, menu);
 }

Finally we need to control which option of the menu is clicked and do something. I achieve this by overriding the OnContextItemSelected method.

    public override bool OnContextItemSelected (IMenuItem item)
    {
      base.OnContextItemSelected (item);

      switch (item.ItemId)
      {
      case Resource.Id.add:
        {
          this.textView.Text = “Add option selected”;
          break;
        }
      case Resource.Id.refresh:
        {
          this.textView.Text = “Refresh option selected”;
          break;
        }
      default:
        break;
      }

      return true;
    }

You can download the working example here.

Drop us a comment or if you have any questions please contact us through our QualTech-Software Solutions or QualTechCloud Integrated Cloud solutions customer form

Leave a Reply