How to create context menu for RecyclerView

Binoy Babu picture Binoy Babu · Oct 20, 2014 · Viewed 79.8k times · Source

How do I implement context menu for RecyclerView? Apparently calling registerForContextMenu(recyclerView) doesn't work. I'm calling it from a fragment. Did anybody have any success implementing this?

Answer

Hardik Shah picture Hardik Shah · Jan 11, 2015

Thanks for the info and comments. I was able to achieve ContextMenu for items in Recyclerview.

Here is what I did

in Fragment's onViewCreated method or Activity's onCreate method:

registerForContextMenu(mRecyclerView);

Then in Adapter add

private int position;

public int getPosition() {
    return position;
}

public void setPosition(int position) {
    this.position = position;
}

make the ViewHolder class implement OnCreateContextMenuListener

public static class ViewHolder extends RecyclerView.ViewHolder 
        implements View.OnCreateContextMenuListener {

    public ImageView icon;

    public TextView fileName;
    public ImageButton menuButton;


    public ViewHolder(View v) {
        super(v);
        icon = (ImageView)v.findViewById(R.id.file_icon);
        fileName = (TextView)v.findViewById(R.id.file_name);
        menuButton = (ImageButton)v.findViewById(R.id.menu_button);
        v.setOnCreateContextMenuListener(this);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, 
        ContextMenu.ContextMenuInfo menuInfo) {
        //menuInfo is null
        menu.add(Menu.NONE, R.id.ctx_menu_remove_backup, 
            Menu.NONE, R.string.remove_backup);
        menu.add(Menu.NONE, R.id.ctx_menu_restore_backup,
            Menu.NONE, R.string.restore_backup);
    }
}

onBindViewHolder method add OnLongClickListener on the holder.itemView to capture the position before the context menu is loaded:

holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        setPosition(holder.getPosition());
        return false;
    }
});

Then in onViewRecycled remove the Listener so that there are no reference issues. (may not be required).

@Override
public void onViewRecycled(ViewHolder holder) {
    holder.itemView.setOnLongClickListener(null);
    super.onViewRecycled(holder);
}

Finally in the Fragment/Activity override the onContextItemSelected as under:

@Override
public boolean onContextItemSelected(MenuItem item) {
    int position = -1;
    try {
        position = ((BackupRestoreListAdapter)getAdapter()).getPosition();
    } catch (Exception e) {
        Log.d(TAG, e.getLocalizedMessage(), e);
        return super.onContextItemSelected(item);
    }
    switch (item.getItemId()) {
        case R.id.ctx_menu_remove_backup:
            // do your stuff
            break;
        case R.id.ctx_menu_restore_backup:
            // do your stuff
            break;
    }
    return super.onContextItemSelected(item);
}