7

I have a LisView with several items. To this I've connected an OnItemClickListener (as an inner class), like this:

lv.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    Toast.makeText(ShoppingListApp02Activity.this, "List item selected:" +  
    items.get(position).getId(), Toast.LENGTH_LONG).show();
    }
});

As is obvious, selecting an entriy displays elements of the object of that entry, in this example the selected Item object's ID (not the list ID, but the objects ID, set when creating the ArrayList items). This works nicely, and enables me to do anything I want with the selected item(s).

Now I'd like to also have a "long-click" listener her, which opens a context menu for the selected ListView item. How do I do that? I've been able to attach an onCreateContextMenu listener to the ListView, but I don't see how I can get the elements of the ArrayList as with the onItemClickListener?

Here's what I've got:

public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {  
    menu.add(0, v.getId(), 0, "Something");
    menu.add(0, v.getId(), 0, "Something else");  
}

Since OnCreateConextMenu takes different parameters than the OnItemClickListener, how to I access the ArrayList's elements like in the OnItemClickListener?

6 Answers6

15

If you decide you still want to use the context menu paradigm:

Consider this for working with lists:

public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {  

    // Get the list
    ListView list = (ListView)v;

    // Get the list item position    
    AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo;
    int position = info.position

    // Now you can do whatever.. (Example, load different menus for different items)
    list.getItem(position);
    ...
}
Eyal Biran
  • 5,656
  • 1
  • 28
  • 29
  • This seems to be the simplest solution. – Head Geek Nov 26 '13 at 02:47
  • How is it possible, to pass the position to the `onContextItemSelected`-Handler? – maja May 28 '14 at 17:04
  • Well, the easiest way to do that would be to store the position/item, when you create the menu (onCreateContextMenu), in a class member (ex: mContextMenuForPosition/mContextMenuForItem). Since onCreateContextMenu will always be called before onContextItemSelected it is assured that the member will have a valid value. – Eyal Biran Jun 01 '14 at 20:56
  • @maja ``` @Override public boolean onContextItemSelected(MenuItem item) { AdapterContextMenuInfo info= (AdapterContextMenuInfo) item.getMenuInfo(); int position = info.position; .... }``` – æ-ra-code Dec 02 '14 at 15:39
  • tried this, but `menuInfo` is null :-( (view is the RecyclerView) – oleh Feb 12 '23 at 15:54
  • seems for RecyclerViews this must be implemented by yourself: https://stackoverflow.com/a/29825764/617889 – oleh Feb 12 '23 at 16:17
7

Instead of messing with context menus (which are used in a wide context - like right-click in PC), ListView offers onItemLongClick event which is a lot more easier to implement. For example:

lv.setOnItemLongClickListener(new OnItemLongClickListener() {
   @Override
   public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2,
       long arg3) {
        // TODO Auto-generated method stub

        return false;
   }
});

This will help you to achieve long-pressed actions on a row.

waqaslam
  • 67,549
  • 16
  • 165
  • 178
  • Man, that is way better. But how do I show a menu or similar when long-clicking? –  Sep 12 '12 at 13:46
  • Simply use an `AlertDialog` with an `ArrayAdapter` and `DialogInterface.OnClickListener` to pop-up your customized menu – waqaslam Sep 12 '12 at 13:57
  • Problem with this is that listItem isn't highlighted on long click. When using context menu, it works okay. – Xdg Jul 16 '17 at 07:33
  • @Xdg The ListView item should highlight with this approach. Make sure you are not overriding the highlight logic through style/theme. – waqaslam Jul 17 '17 at 12:39
5

Open the context menu of the view within the event handler for the long press event on the row view.

convertView.setOnLongClickListener(new OnLongClickListener() {

            @Override
            public boolean onLongClick(View v) {
                ((Activity)mContext).openContextMenu(v);
                return true;
            }
        });

This way both the click on the view and the long press context menu works on the listview row item.

Gopinath
  • 12,981
  • 6
  • 36
  • 50
4

First register context menu into your listview to open context menu:

registerForContextMenu(YOUR LIST-VIEW OBJECT);

then you can use your onCreateContextMenu() method:

public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {  
    menu.add(0, v.getId(), 0, "Something");
    menu.add(0, v.getId(), 0, "Something else");  
}

You actually dont need to use longClickListener with your listview to use ContextMenu.

Hope it will help you.

Rushabh Patel
  • 3,052
  • 4
  • 26
  • 58
  • Uhm. That's more or less what I did, isn't it? I still don't get access to the ListView's ArrayList in the onCreateConextMenu. –  Sep 12 '12 at 14:06
  • yes for that you need to declare your listview and adapter accessible through out the activity. It may be help you to solve your problem. – Rushabh Patel Sep 12 '12 at 14:16
2

I will let you go through the below written example and see how it is implemented by using onContextItemSelected()

public void onCreateContextMenu(ContextMenu menu,
        View v,
        ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);


    menu.setHeaderTitle(title);

    menu.add(0, CMD_EDIT, 0, R.string.context_menu_edit);
    menu.add(0, CMD_DELETE, 0, R.string.context_menu_delete);


}

@Override
public boolean onContextItemSelected(MenuItem item) {

    switch (item.getItemId()) {
    case CMD_EDIT:
        any_function();//add your functionality here i.e. what you want to do
        return true;
    case CMD_DELETE:
        **confirmDelete**();
        return true;
    default:
        return super.onContextItemSelected(item);
    }
}

Hope this helps...

mohit
  • 147
  • 2
  • 14
0

Try this for a View item in recycleView

viewForContextMenu.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
        @Override
        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
            menu.add("Context Menu Item1").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {

                    //What should happent on selecting context menu item 1
                    return true;
                }
            });
        }
    });

You can use it with setting data to a ViewHolder item