Blog

Android: Context menu example (on long press, gridview)

I received several requests regarding how I created a context menu (the menu activated on a long press) using a gridview and how to call functions such as saving a sound file from this. So I have created a quick example to explain this:

Tutorial

To implement a context menu (long press menu) you first need to include the following imports:

import android.view.ContextMenu;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;

We start a very simple project, with the layout having a single button named button_example:

Android context menu example

Android context menu example

We then use registerForContextMenu in the onCreate of the activity to tell android that we want this view to create a menu when it is long pressed. This is not limited to buttons, this will work for other views too. You must register each view that you want to have associated with the context menu.

Button btn = (Button) findViewById(R.id.button_example);
registerForContextMenu(btn);

You then need to override the onCreateContextMenu method to create the menu:

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {
	super.onCreateContextMenu(menu, v, menuInfo);
		menu.setHeaderTitle("Context Menu");
		menu.add(0, v.getId(), 0, "Action 1");
		menu.add(0, v.getId(), 0, "Action 2");
	}
android context menu example

android context menu example

And override onContextItemSelected to preform the action when an option is selected from this menu:

    @Override
	public boolean onContextItemSelected(MenuItem item) {
       	if(item.getTitle()=="Action 1"){function1(item.getItemId());}
    	else if(item.getTitle()=="Action 2"){function2(item.getItemId());}
    	else {return false;}
	return true;
	}

function1 and function2 are just place-holders at the moment that toast a message when they are used. In the above example we are choosing between Action 1 and Action 2 which define which function will be run when an item is selected. We have passed the ID of the view through the context menu and into this function so we can tell what the user was pressing when the context menu was created.

calling a function after a context menu item was pressed

calling a function after a context menu item was pressed

Examples

If you create a gridview and give each item a unique ID then you can use this method to preform actions based on each item. This is the method I use for my soundboard applications to save the sounds to the SD card as a notification or ringtone:

counterstrike 1.6 soundboard context menu

counterstrike 1.6 soundboard context menu


Unreal Tournament soundboard context menu

Unreal Tournament soundboard context menu

Source

Below is the source code:

package com.contextmenu.test;

import android.app.Activity;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.Button;
import android.widget.Toast;

public class test extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        Button btn = (Button) findViewById(R.id.button_example);
        registerForContextMenu(btn);        
    }
    
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {
	super.onCreateContextMenu(menu, v, menuInfo);
		menu.setHeaderTitle("Context Menu");
		menu.add(0, v.getId(), 0, "Action 1");
		menu.add(0, v.getId(), 0, "Action 2");
	}

    @Override
	public boolean onContextItemSelected(MenuItem item) {
       	if(item.getTitle()=="Action 1"){function1(item.getItemId());}
    	else if(item.getTitle()=="Action 2"){function2(item.getItemId());}
    	else {return false;}
	return true;
	}
    
    public void function1(int id){
    	Toast.makeText(this, "function 1 called", Toast.LENGTH_SHORT).show();
    }
    public void function2(int id){
    	Toast.makeText(this, "function 2 called", Toast.LENGTH_SHORT).show();
    }
}

74 Comments

  1. Wildheart Baby

    Excellent tutorial, the only problem I’m having is that the filename never gets picked up at anypoint, I’m using

    yourmove.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
    if (FilmSound.isPlaying())
    {
    FilmSound.stop();
    FilmSound.reset();
    FilmSound = MediaPlayer.create(getApplicationContext(), R.raw.yourmove);
    FilmSound.start();
    }
    else {FilmSound = MediaPlayer.create(getApplicationContext(), R.raw.yourmove);
    FilmSound.start(); }
    }
    }
    );

    as the code for playing the sound file, is there a way of incorporating the context menu and my code.

  2. mat

    I’m afraid you haven’t given enough information to explain what problem your having. Also your code seems inefficient, do you have this for each button? I’d use an array of sound files and create a function to play the sounds based on what view is passed to the OnClickListener. I’ll post another tutorial on how to implement OnClickListners into your activity and just switch based on view id.

  3. Wildheart Baby

    Yeah each button is has the code tied to it, I’m really new to java programming and this was the easiest way to get what I was after.

    You press a button the code checks if the sound is playing so as to avoid the sounds repeating and then sets up and plays the sound sample.

    My problem is that this is obviously inefficient but I can’t see how I can do it any other way.

  4. Hoodis

    I too have some questions.

    I have a onClickListener/OnClick which plays a soundfile. Later I implemented this ContextMenu by following your guide. Now I want to know how to bring the buttons soundfile
    and put it into for example: if(item.getTitle()==”Action 1″){function1(soundfilethatIwanthere);}

    I hope you understand my problem/question.
    Thanks in advance and thanks alot for this guide! 🙂

  5. mat

    @Wildheart Baby Posted up a tutorial for grouping your onclicklisteners.

    @Hoodis In your context menu you can pass along the ID of the View that has called the context menu (I.E. Which button was long pressed)

    In the onCreateContextMenu, this line passes v.getId(), which is the View’s id
    menu.add(0, v.getId(), 0, “Action 1”);

    In the onContextItemSelected, this line calls the function passing this ID again
    function1(item.getItemId());

    So in function1 you’d simple need to have something that chooses which sound to act upon based on which View ID was passed to it.

    Hope that makes sense

  6. Marc

    Great tutorial.

    Is it possible to have multiple context menus? I have an app with many buttons and I would like each button to have its own context menu. I tried to understand your response to Hoodis, but I wanted to break it down to a separate context menu for each button.

  7. brybam

    Hi mat, I was wondering if you could maybe take a look at the code i made using your example over at

    http://stackoverflow.com/questions/3315269/android-trouble-with-using-multiple-context-menus

    I seem to have trouble getting more than one context menu to work :/

  8. mat

    @brybam Looks like someone already replied to you. You only need one onCreateContextMenu and onCreateContextMenu and you just need to register all your buttons for a context menu.

    Hope you get it working.

  9. Ray Dios Haque

    Hello, great tutorial!! I have incorporated this into a project, but I am a total newb’ to this and I need some help trying to do something simple. Can you tell me how you would refer to what button was pressed within the called function?

    In other words – if I press and hold the first button, how could I then reference the “first button” within function1. Example – I hold down button one. I choose action 1, and it says “Function one called : Button title is It’s gonna blow”.

    I am actually trying to take a sounboard that I all ready made, and incorporate your “save as Ringtone” technique. 🙂

  10. mat

    If you look up a few posts to my reply to @Hoodis, then you will see this:

    ### QUOTE ###

    In your context menu you can pass along the ID of the View that has called the context menu (I.E. Which button was long pressed)
    In the onCreateContextMenu, this line passes v.getId(), which is the View’s id
    menu.add(0, v.getId(), 0, “Action 1″);
    In the onContextItemSelected, this line calls the function passing this ID again
    function1(item.getItemId());
    So in function1 you’d simple need to have something that chooses which sound to act upon based on which View ID was passed to it.

    ### UNQUOTE ###

    Which can be used to differentiate between the different views. Hope this helps

  11. […] hopefully your all done, you could then go on to add a context menu(menu on long press) to your buttons. If you have any questions or want something explaining a bit […]

  12. Ambiguous Error

    Hi Matt,
    Thanks for all of your tutorials, real food for thought & an inspiration.
    Would you mind expanding on you last comment regarding:

    “something that chooses which sound to act upon based on which View ID was passed to it”

    Look forward to your response, I’ve hit a bit of a wall

  13. Ambiguous Error

    I managed to solve the problem with a switch /case query, not perhaps the most efficient solution but it works all the same :o)

  14. Aaron

    Along the same lines, how do I make

    if (savering(R.raw.sound1)){

    and

    String filename=”sound1″+”.ogg”;

    and

    values.put(MediaStore.MediaColumns.TITLE, “sound1”);

    dynamic?

    I made a soundArray, which works, following your comments to someone else but could not figure out the last part, savering(soundArray[ressound]); to work.

    Any help or hints would be gretly appreciated.

    Thanks

  15. Alex

    Hi, I am having trouble with one thing. I am working on a soundboard app. I followed your tutorial and created a GridView of image buttons via a custom ButtonAdapter. Now, how do I register the entire GridView and its children for the context menu? Normally, I would just register each button individually… something along the lines of:

    Button btn = (Button) findViewById(R.id.button01);
    registerForContextMenu(btn);

    The problem is that the buttons created by the custom ButtonAdapter aren’t in the R.java file, so I can’t use that method.

    I tried the following code (hoping that registering the gridview would also register the children within it):

    GridView gridview = (GridView) findViewById(R.id.gridview);
    registerForContextMenu(gridview);
    gridview.setAdapter(new ButtonAdapter(this));

    I also tried changing around the order of the code above, but nothing seems to work. Can you help me?

  16. mat

    @Aaron: Use arrays

    @Alex: In your ButtonAdapter you can register for the context menu when you create each view. If you can’t find where let me know and I might be able to find some code.

  17. Alex

    Thanks, mat. I’ve tried a few things, but I still can’t get it to work right. I keep getting this error:

    “The method registerForContextMenu(Button) is undefined for the type ButtonAdapter”

  18. mat

    Does your ButtonAdapter extends BaseAdapter ? If not it should, if so, it should work.

  19. Alex

    Yep, the ButtonAdapter extends BaseAdapter. I still can’t get it to work.

  20. Big Joe

    nice post!
    thank you 🙂

  21. Aditya

    I didnt get the Context menu…..

  22. Basil

    Well done. What I missed for a long time that might help out a few folks is… you need to set an ID FOR YOUR VIEWs explicitly … yourview.setId(someInt); the view does not have this by default and you will see -1 if its not set yet.

  23. Lance

    I had Alex’s problem ( method registerForContextMenu not registered)

    Fix:
    import android.view.MenuItem;

    🙂

  24. Jon

    Lance – That doesn’t work for me. Still undefined (I’ve tried cleaning), I’ve even tried importing android.view.ContextMenu.

  25. govind9ew

    nice tutorial. but i am facing some problem in adding context menu to a custom view. i have tried to send my custom view’s variable say “upperview” like this
    registerForContextMenu(upperview);
    i have added rest of the function in my code as shown by this tutorial.

    but its nt working. no context menu appear even after long touch on screen.. plz guide if u know anything abt my prob.

  26. Jim

    Thanks! I now understand Context Menus much better and will be using them in my applications.

  27. Joel Nagy

    After reading a dozen other sites and having all sorts of issues with Eclipse your example was the cleanest and worked on the first try. Thanx.

  28. droopie

    wow thats a great looking soundboard. wonder if you have the source code up for us to play with

  29. Shubham

    How can i approach to make an circular menu..pls guide me.

    thanks

  30. nitin

    hey ,
    i need to open menu on Button click , how to do it that ?

  31. nitin

    hey , i need to open menu on single Button click , not on long click!!

    how to do it that ?

    plz reply me on my email id :

    justnitnijadhav@gmail.com

  32. Rick Buiten

    For opening a menu on single Button click you also have to add the following code:

    linearLayout.setOnClickListener(actionOnClickListener);

    private View.OnClickListener actionOnClickListener = new View.OnClickListener() {
    public void onClick(View view) {
    if(view != null){
    view.showContextMenu();
    }
    }
    };

  33. Ranjit(Learning Android)

    thnx it is really helpful to me……..

  34. Chris

    Hello Mat,

    I’m having trouble differentiating between which button is pressed to bring up the context menu and then get this working into the functions.

    Currently I have this;

    public void function1(int id){
    // save ring tone function
    switch (id) {
    case test:
    Toast.makeText(this, “TEST BUTTON PRESSED”, Toast.LENGTH_SHORT).show();

    case test2:
    Toast.makeText(this, “TEST2 BUTTON PRESSED”, Toast.LENGTH_SHORT).show();
    }
    }

    Where test and test2 are buttons which bring up the context menu but it just doesn’t seem to be working? Am I totally of course here as I’m very new to Java programming.

    Any suggestions?
    Thanks.

  35. Varki

    Hi, nice tutorial!

    Anyone knows how to implement an “add to favorites” option that context menu?

    Tnx!!

  36. Jayant Umrani

    I am facing wiered thing. The override declaration
    @Override
    24. public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo)

    gives error stating that remove @Override.

    When I remove the compile error is gone but when I run the program no context menu is shown.

    I am using Android 2.3.3 and testing on Samsung Charge (Verizon)

    Any idea what is the issue?

  37. Surekha Methuku

    Awesome tutorial, I got my context menu in no time!!
    Is it good or possible to use context menu for a button click(not long click)?

  38. Jens vanderhaeghe

    Thank you, needed this for my college project, great tutorial!

  39. Adit

    How can i change the font of the menuitems?

  40. Anonymous

    Thank you so much!!!
    I’ve been looking for this for the past few days, and found nothing!!
    Thanks to you I can process with my plans to develop an app.

  41. say

    Is it possible to do this in just a single press on a button?

  42. mat

    To open the context menu try calling openContextMenu();

  43. say

    I will. Thanks for the quick reply. God bless

  44. Sam

    Hi..I am developing a simple android app using webview. my website, which i am using in webview, has some images. How can i make users ave those images to their sd cars? please tell me soon

  45. Jefferson

    thank you so much!!

  46. Meena

    Hi,
    I am new to Android. How should i create a GridView and if user focused on EditText, it should be able to open context Menu . In Context Menu two options must be included and those options should be arranged in a GridView. How could i do this ?

  47. Henrik

    Thanks! Excellent!

  48. Hamoosh

    Thanks ,
    I’m making an app also let user to set sound as a ring tone
    and I play sounds when user click on gridview

    and I tried to make that code to set sound as ring tone , but I’m stuck how can I get the id or position of that exact sound user clicked on

    I save my sounds as Integer Array ‘ mSoundsIDs ‘, how can I pass mSoundsIDs[position] to my setting function ?

  49. Rajendra Verma

    hi, thank you help..!

    I liked to asked, where is long pressed action listener… in code please let me know..

  50. Rajendra Verma

    someView.setOnLongClickListener(new View.OnLongClickListener() {
    // Called when the user long-clicks on someView
    public boolean onLongClick(View view) {
    if (mActionMode != null) {
    return false;
    }

    // Start the CAB using the ActionMode.Callback defined above
    mActionMode = getActivity().startActionMode(mActionModeCallback);
    view.setSelected(true);
    return true;
    }
    });

Leave a Comment

Your email address will not be published. Required fields are marked *