Action bar

Action bar

There are two types of Android menus

  • Options menu
    the menu that appears when you press the menu button
    this type of menus is binded to the activity (Every activity can have one options menu)
  • Context menu
    the menu when you do a long press on a view (like Text view or list item)
    this type of menus is binded to the view (Every view can have one context menu)


There are another type “Submenus” it’s the menu that appears when you press on a menu item that contains other menu items

Menu XML Resource
Menu structure contains some Menu items, every menu item may contain label or icon or both
Context menu only displays labels not icons, Options menu displays both.

sample menu item would be an item tag that contains android:id, android:title and android:icon attributes
the id value should be in the form @+id/x where x is the actual id that identifies this menu item
the icon should be a drawable resource (an image in the drawable directory) in the form @drawable/x where x is the image name without extension(if you have an image called test.png in the drawable directory, the icon attribute value should be @drawable/test )
the label should be a string or a string resource

	

Submenus
to insert a menu into menu item(Submenu)

	
		
			
			
		
	

Menu resource file
The xml items should be enclosed in a menu tag
this is an example to the menu file


  
	
	
	
	
	
		
			
			
		
	
  

Options menu life cycle
The options menu has three main function that I can override in any activity

  • public boolean onCreateOptionsMenu(Menu menu)
    fires in the first press on menu button in an activity
    It passes a reference to the menu that should appear to the user
  • public boolean onPrepareOptionsMenu(Menu menu)
    fires in every press on the menu button
    It passes a reference to the menu that should appear to the user
  • public boolean onOptionsItemSelected(MenuItem item)
    fires when a user select a menu item
    It passes a reference to the menu item already selected by the user
Options menu

Options menu

Activate Options menu
The ideal solution is to load your Menu from XML resource file in the first press of menu item only (not every time the user press the menu button as you depend on a static menu)
the method have one argument of type Menu, this is a reference to the menu that would be displayed.
my rule is to fill (inflate) it.
we can get a menu inflater object by calling getMenuInflater() from the activity or creating a new instance of MenuInflater passing the context to it.
The menu inflater takes two arguments

  • The resource file from which the menu would be loaded
  • The menu that would be inflated(loaded from the resource file)
    /**
     * Launched only once, in the first press of menu button 
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	
    	// Menu inflater get the menu items from XML resource and populate a menu with them
    	MenuInflater menuInflater = getMenuInflater();
    	// inflate:  takes two arguments
    	// 1: source from XML resource
    	// 2: destination menu reference
    	menuInflater.inflate(R.menu.options, menu);
    	
    	return super.onCreateOptionsMenu(menu);
    }

Respond to user’selection
The application is now ready to display a menu when the user press the menu button.
the missing part is to do an action when a menu item is pressed, we can make so by using the method onOptionsItemSelected
When user selects a menu item, a callback goes to the method onOptionsItemSelected holding this menu item
a good way to handle the selection is to get the item id of the menu and do a switch-case among all the menu items ids

    /**
     * Launched when selecting menu item
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    	
    	switch (item.getItemId()) {
		case R.id.box:
			Toast.makeText(this, "this is a box", Toast.LENGTH_SHORT).show();
			break;
		case R.id.house:
			Toast.makeText(this, "this is a house", Toast.LENGTH_SHORT).show();
			break;

		default:
			break;
		}
    	
    	return super.onOptionsItemSelected(item);
    }
Context menu

Context menu

Context menu
building a context menu is so similar to options menu
we should write a similar XML file (we can use the same file)
the difference is that options menu applies to the whole activity, but the context menu applies to a view on the activity

Edit layout
We should edit our layout to include one or more views with ids


    
	
	

Edit Activity
in the activity we should bind the view with its corresponding XML menu resource
when the activity loaded(usually in onCreate method) we would tell that a specific view has a context menu, we can do so by registering this view using registerForContextMenu method

	View activeView;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);
        
        // get the view from xml
        activeView = findViewById(R.id.text);
        
        // register the context menu for a specific view
        registerForContextMenu(activeView);
    }

Now when you do a long press on that view it should display a context menu.
like Options menu, it fires a method called onCreateContextMenu, passing an instance of ContextMenu to be filled and an instance of View(the view that has been pressed)
in the method body we would use the MenuInflater to load the Menu resource file to the empty menu instance
also if we have many views that has context menus, we must check the passed view first before inflating.

    /**
     * Launched Every time we do a long press on the view registered for the context menu
     */
    @Override
    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
    	super.onCreateContextMenu(menu, view, menuInfo);
    	MenuInflater menuInflater = getMenuInflater();
    	// check the view to provide the corresponding menu to it
    	if(view == activeView)
    		menuInflater.inflate(R.menu.options, menu);
    }

to make an action when we press on any context menu item we use a method called onContextItemSelected that has the same signature as onOptionsItemSelected

    @Override
    public boolean onContextItemSelected(MenuItem item) {
    	return onOptionsItemSelected(item);
    }