OnCreateContextMenu and ListView items
Asked Answered
V

6

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?

Vineyard answered 12/9, 2012 at 13:22 Comment(0)
A
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);
    ...
}
Ahimsa answered 6/2, 2013 at 10:52 Comment(6)
This seems to be the simplest solution.Spitsbergen
How is it possible, to pass the position to the onContextItemSelected-Handler?Kingly
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.Ahimsa
@Kingly ``` @Override public boolean onContextItemSelected(MenuItem item) { AdapterContextMenuInfo info= (AdapterContextMenuInfo) item.getMenuInfo(); int position = info.position; .... }```Koo
tried this, but menuInfo is null :-( (view is the RecyclerView)Norma
seems for RecyclerViews this must be implemented by yourself: https://mcmap.net/q/187523/-how-to-create-context-menu-for-recyclerviewNorma
B
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.

Borosilicate answered 12/9, 2012 at 13:27 Comment(4)
Man, that is way better. But how do I show a menu or similar when long-clicking?Vineyard
Simply use an AlertDialog with an ArrayAdapter and DialogInterface.OnClickListener to pop-up your customized menuBorosilicate
Problem with this is that listItem isn't highlighted on long click. When using context menu, it works okay.Kalman
@Kalman The ListView item should highlight with this approach. Make sure you are not overriding the highlight logic through style/theme.Borosilicate
J
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.

Joselow answered 12/9, 2012 at 13:42 Comment(4)
it will return ListView as View in onLongClick, not the item's viewBorosilicate
I meant to set the longclick listener on the view which is returned from the getView() method.That's why I called it as convertview.Joselow
then you need to use setOnItemLongClickListener which will return the View made from getView(). i.e. the row itemBorosilicate
really a smart waySidman
E
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.

Edger answered 12/9, 2012 at 13:46 Comment(2)
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.Vineyard
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.Edger
R
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...

Remde answered 1/6, 2013 at 12:34 Comment(0)
H
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

Haemophilic answered 11/11, 2015 at 13:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.