NOTE:

NOTE: Of late, I have been getting requests for very trivial problems that many of you are facing in your day-to-day work. This blog is not to solve your "project" problems - surely not a "Support" site.
I just love to share my knowledge in my spare time and would appreciate any questions or feedback on the articles and code I have shared. I also do appreciate thought-provoking questions that would lead me to write more articles and share.
But please do not put your day-to-day trivial problems here. Even if you do, you most probably would not get a response here.
Thanks

Search This Blog

x

Sunday 8 May 2011

Context Menu | Android Developer Tutorial


This is a follow up to the Options Menu Tutorial shared earlier.

To recap, the Context Menu is a floating list of menu items that appears when a user touches and holds a particular item displayed in the view, which has a menu associated with it.

Going straight to the example, first I create a ListView with names of pens displayed. When one presses and holds one of the names for a long time, the context menu appears as shown here:

And when you click on any of the context menu shown above, the screen that appears is:

Let’s go to the code.

First, the mundane step of creating a Listview (you can see the ListView tutorial for more explanation on this).  
I create a class ShowContextMenu extending the ListActivity. In its OnCreate(…) method, I associate the Listview array with the ListAdapater as shown here:

public class ShowContextMenu extends ListActivity {
     

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setListAdapter(new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, getResources().getStringArray(R.array.names)));

…       
    }

Note that instead of hard-coding the list items as string array within the class, I have followed the best practice of externalizing the strings into a strings.xml resource class. Hence I use getResources().getStringArray(R.array.names) to retrieve the array of pen names that I want to display in the List.  The strings.xml file in the value folder has this entry:

<string-array name="names">
      <item>MONT Blanc</item>
      <item>Gucci</item>
      <item>Parker</item>
      <item>Sailor</item>
      <item>Porsche Design</item>
      <item>Rotring</item>
      <item>Sheaffer</item>
      <item>Waterman</item>
</string-array>

Once this Listview has been created, now we want to associate a ContextMenu with each of the rows in the Listview Item. i.e. is a user were to long-press one of the items, a menu should appear. For this we add the following line as well in the onCreate(..) method.
registerForContextMenu(getListView());

But how do we create the ContextMenu? Whenever the long-press happens, the onCreateContextMenu(…) method is invoked. So, we need to override this method as shown below:

    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
      super.onCreateContextMenu(menu, v, menuInfo);
      MenuInflater inflater = getMenuInflater();
      inflater.inflate(R.menu.context_menu, menu);
    }

Here again, just as in Options Menu tutorial, I use a MenuInflater to create the context menu rather than do it programmatically. This is certainly a best practice of keeping the concerns separated. The View and the programming logic are kept separate as meant to be in Android Programming.  The context menu consists of 4 items – Edit, Save, Delete, View. So, here is how it is defined in the context_menu.xml in the res/menu folder:

<menu
  xmlns:android="http://schemas.android.com/apk/res/android">
      <item android:id="@+id/edit"
              android:title="@string/edit" />
      <item android:id="@+id/save"
            android:title="@string/save" />
      <item android:id="@+id/delete"
            android:title="@string/delete" />
      <item android:id="@+id/view"
            android:title="@string/view" />
</menu>

I have an id that is associated with each of the menu items that uniquely identifies the menu item selected. And I have a String associated with it which is what is displayed on the Menu.

Now that the context menu is created, how to handle when the menu item is clicked? For this we need to override the onContextItemSelected(…) method as shown below;

    public boolean onContextItemSelected(MenuItem item) {
      AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
      String[] names = getResources().getStringArray(R.array.names);
      switch(item.getItemId()) {
      case R.id.edit:
            Toast.makeText(this, "You have chosen the " + getResources().getString(R.string.edit) +
                        " context menu option for " + names[(int)info.id],
                        Toast.LENGTH_SHORT).show();
            return true;
      …………………..
      default:
            return super.onContextItemSelected(item);
      }

This is the callback method invoked when a context menu item is clicked. The callback get the reference to the clicked menu item as the parameter item.

I use the method item.getItemId() to retrieve the id of the item clicked. This is the same id that is defined in context_menu.xml. So, based on the id, I used a switch statement to jump to the appropriate action. Here the action is just to toast a message that tell which context menu was clicked for which ListView item. How do I retrieve the ListView item clicked?

Extra information about the menu is returned by calling item.getMenuInfo().  Info.id would be the ListView id. I use this id to retrieve the name of the pen  as in names[(int)info.id]

That is it. Do you want the complete code? Here it is.

20 comments:

  1. Thanks... Great Info.

    ReplyDelete
  2. hi i am rajesh new to android i want solution for multiscreen suport ui design in android..
    please help me ..


    Thank you

    ReplyDelete
  3. nice one,easy to understand...........

    ReplyDelete
  4. Its really so simple and easy to understand. Nice presentation.
    Web Shopping Cart
    Free Ecommerce Software

    ReplyDelete
  5. Hi
    This is pradeep. i tried contextView programme. i followed whatever mentioned above, but in the list of contexts,i want to delete one context(eg:Gucci).How is it possible.write coding for that one .

    ReplyDelete
  6. Hi, could you teach me how do i display my contextmenu once i click on my tabhost, instead of longclick it? thanks

    ReplyDelete
  7. hi i am using list view with custom adapter in which i am taking image view ,text view and two button ,this is the one cell layout...i am display this list view in popup window. i want to show context menu when i click one of item of list but i unable to do this ...
    i think it is not possible with custom adapter..

    ReplyDelete
  8. nice programming...........Geetha

    ReplyDelete
  9. how to convert .wav file into .mdi file android is possible r not

    plz rply as early as possible

    ReplyDelete
  10. Thanks! You help me a lot

    ReplyDelete
  11. Hey i really liked your tutorial. I want to delete items from a list view. how am i suppose to do it..?? can you please help.?

    ReplyDelete
  12. android sucks!! its crap if u have seen wp7..

    ReplyDelete
  13. How would you navigate between two fragments. Let's say I have fragment A. On clicking on an item in fragment A takes me to fragment B and again same action takes me to fragment C. If I long press on an item in fragment C, onCreateOptionsMenu() works fine, but onContextItemSelected() doesn't give me the desired result. could you please tell me the reason and solution for it?

    ReplyDelete
  14. the ID must be static or dynamic?

    ReplyDelete
  15. This comment has been removed by the author.

    ReplyDelete
  16. This tutorial helped a lot as an entry point into programming android context menus - thank you very much for sharing your knowledge :) !

    ReplyDelete
  17. Thanks, it helped me a lot

    ReplyDelete