How to create context menu for RecyclerView How to create context menu for RecyclerView android android

How to create context menu for RecyclerView


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).

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

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

@Overridepublic 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);}


You can't directly implement these method like onClickListener,OnContextMenuListener etc. because RecycleView extends android.view.ViewGroup. So we cant directly use these method.We can implement these methods in ViewHolder adapter class.We can use context menu in RecycleView like this way:

public static class ViewHolder extends RecyclerView.ViewHolder implements OnCreateContextMenuListener {        TextView tvTitle;    ImageView ivImage;        public ViewHolder(View v) {        super(v);        tvTitle =(TextView)v.findViewById(R.id.item_title);        v.setOnCreateContextMenuListener(this);                    }}

Now we follow the same procedure while implements the context menu.

@Overridepublic void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {         menu.setHeaderTitle("Select The Action");        menu.add(0, v.getId(), 0, "Call");//groupId, itemId, order, title       menu.add(0, v.getId(), 0, "SMS");     }

If you get any difficulties ask in comment.


The current answer is not correct. Here's a working implementation:

public class ContextMenuRecyclerView extends RecyclerView {  private RecyclerViewContextMenuInfo mContextMenuInfo;  @Override  protected ContextMenu.ContextMenuInfo getContextMenuInfo() {    return mContextMenuInfo;  }  @Override  public boolean showContextMenuForChild(View originalView) {    final int longPressPosition = getChildPosition(originalView);    if (longPressPosition >= 0) {        final long longPressId = getAdapter().getItemId(longPressPosition);        mContextMenuInfo = new RecyclerViewContextMenuInfo(longPressPosition, longPressId);        return super.showContextMenuForChild(originalView);    }    return false;  }  public static class RecyclerViewContextMenuInfo implements ContextMenu.ContextMenuInfo {    public RecyclerViewContextMenuInfo(int position, long id) {        this.position = position;        this.id = id;    }    final public int position;    final public long id;  }}

In your Fragment (or Activity):

@Overridepublic void onViewCreated(View view, @Nullable Bundle savedInstanceState) {    super.onViewCreated(view, savedInstanceState);    mRecyclerView = view.findViewById(R.id.recyclerview);    registerForContextMenu(mRecyclerView);}@Overridepublic void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {    super.onCreateContextMenu(menu, v, menuInfo);    // inflate menu    MenuInflater inflater = getActivity().getMenuInflater();    inflater.inflate(R.menu.my_context_menu, menu);}@Overridepublic boolean onContextItemSelected(MenuItem item) {    return super.onContextItemSelected(item);    RecyclerViewContextMenuInfo info = (RecyclerViewContextMenuInfo) item.getMenuInfo();    // handle menu item here}

And finally, in your ViewHolder:

class MyViewHolder extends RecyclerView.View.ViewHolder {    ...    private void onLongClick() {        itemView.showContextMenu();    }}