Android Menu – Handling Click Events & Changing Menu Items at Runtime

android-menu-events-runtime-changeWhen a user clicks on a menu item the system will generate an event that we can listen to it and handle it. As an example we will see how to handle a click to add or remove a menu item at runtime.

 

Objectives:

  • How to handle menu click events?
  • How to add a new menu item dynamically to “actionbar” at runtime?

Environment & Tools:

  • Android Developer Tools (ADT) (or Eclipse + ADT plugin)
  • AVD Nexus S Android 4.3 “emulator” or,
  • Min SDK 8

( 1 ) Create Android Application With One Menu Item

  • File >> New >> Android Application
  • Enter App name: android-menu-events-change
  • Pakcage: com.hmkcode.android
  • Keep other defualt selections, go Next  till you reach Finish

Icons used in this sample can be found in GitHub or Download the Action Bar Icon Pack.

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

    <item
        android:id="@+id/action_addItem"
        android:orderInCategory="100"
        android:showAsAction="always"
        android:icon="@drawable/ic_content_new"
        android:title="Add New Item"/>

</menu>
  • If you run the application on the emulator you will get

  • To change application name “title beside android logo” to App go to res/values/string.xml
  • res/values/string.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">App</string>
    <string name="hello_world">Hello world!</string>

</resources>

( 2 ) Handling Click Events

Now what we want to do is, when the user clicks on the add icon “+” we will add a new item and change the add icon to remove “X” icon.

  • onOptionsItemSelected() will be called when a user clicks on an item.
  • onOptionsItemSelected(MenuItem item) MenuItem object is passed as a parameter which is a reference to the clicked item. Using this object we can know which item has been clicked.
package com.hmkcode.android;

import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

@SuppressLint("NewApi")
public class MainActivity extends Activity {

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

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	boolean canAddItem = false;
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

    	if(item.getItemId() == R.id.action_addItem){
    		// ( 1 ) add a new item 
                // ( 2 ) change add to remove
    	}
    	else{
    	        // if a the new item is clicked show "Toast" message.
    	}

    	return super.onOptionsItemSelected(item);
	}
}

( 3 ) Adding & Changing Items at Runtime

  • We need to call onPrepareOptionsMenu(Menu menu) to add, remove and modify menu items.
  • On Android 2.3.x and lower, the system calls onPrepareOptionsMenu() each time the user opens the options menu (presses the Menu button).
  • On Android 3.0 and higher, we need to call invalidateOptionsMenu() to request that the system call onPrepareOptionsMenu().
package com.hmkcode.android;

import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

@SuppressLint("NewApi")
public class MainActivity extends Activity {

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

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	boolean canAddItem = false;
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		Toast toast;
    	if(item.getItemId() == R.id.action_addItem){
    		invalidateOptionsMenu();
    	}
    	else{
    		toast = Toast.makeText(this, item.getTitle()+" Clicked!", Toast.LENGTH_SHORT);
    		toast.show();
    	}

    	return super.onOptionsItemSelected(item);
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {

		if(canAddItem){
			menu.getItem(0).setIcon(R.drawable.ic_content_remove);
			MenuItem mi = menu.add("New Item");
			mi.setIcon(R.drawable.ic_location_web_site);
			mi.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM);
			canAddItem = false;
		}
		else{
			menu.getItem(0).setIcon(R.drawable.ic_content_new);
			canAddItem = true;
		}

		return super.onPrepareOptionsMenu(menu);
	}

}

 

Source Code @ GitHub