How to create context menu for RecyclerView

后端 未结 21 2577
日久生厌
日久生厌 2020-11-28 01:20

How do I implement context menu for RecyclerView? Apparently calling registerForContextMenu(recyclerView) doesn\'t work. I\'m calling it from a fra

相关标签:
21条回答
  • 2020-11-28 02:20

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

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mRecyclerView = view.findViewById(R.id.recyclerview);
        registerForContextMenu(mRecyclerView);
    }
    
    @Override
    public 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);
    }
    
    @Override
    public 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();
        }
    }
    
    0 讨论(0)
  • 2020-11-28 02:20

    I have been using this solution for sometime now and has worked pretty good for me.

    public class CUSTOMVIEWNAME extends RecyclerView { 
    
    public CUSTOMVIEWNAME(Context context) {
        super(context);
    }
    
    public CUSTOMVIEWNAME (Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    public CUSTOMVIEWNAME (Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    
    private RecyclerContextMenuInfo mContextMenuInfo;
    
    @Override
    protected ContextMenu.ContextMenuInfo getContextMenuInfo() {
        return mContextMenuInfo;
    }
    
    @Override
    public boolean showContextMenuForChild(View originalView) {
        final int longPressPosition = getChildAdapterPosition(originalView);
        if (longPressPosition >= 0) {
            final long longPressId = getAdapter().getItemId(longPressPosition);
            mContextMenuInfo = new RecyclerContextMenuInfo(longPressPosition,    `           longPressId);
            return super.showContextMenuForChild(originalView);
        }
        return false;
    }
    
    public class RecyclerContextMenuInfo implements ContextMenu.ContextMenuInfo             {
    
        public RecyclerContextMenuInfo(int position, long id) {
            this.position = position;
            this.id = id;
        }
    
        final public int position;
        final public long id;
    }
    }
    

    Now in your fragment or Activity implement the following methods.

      @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
    
        // Inflate Menu from xml resource
        MenuInflater menuInflater = getMenuInflater();
        menuInflater.inflate(R.menu.context_menu, menu);
    }
    
    @Override
    public boolean onContextItemSelected(MenuItem item) {
        ContextMenuRecyclerView.RecyclerContextMenuInfo info = (ContextMenuRecyclerView.RecyclerContextMenuInfo) item.getMenuInfo();
        Toast.makeText(InstanceOfContext , " User selected  " + info.position, Toast.LENGTH_LONG).show();
    
        return false;
    }
    

    Finally Register for the contextMenu on the recyclerview

       //for showing a popup on LongClick of items in recycler.
        registerForContextMenu(recyclerView);
    

    That should work!

    0 讨论(0)
  • 2020-11-28 02:21

    Here's a simpler way to do it with Kotlin that worked for me. The major challenge is figuring out the position of the item that was pressed. Inside your adapter, you can place this code snippet and it'll be able to capture the position of the item for whom the context menu is shown; that's all.

    override fun onBindViewHolder(holder: YourViewHolder, position: Int) {
    
    ...     
    
        holder.view.setOnCreateContextMenuListener { contextMenu, _, _ -> 
                contextMenu.add("Add").setOnMenuItemClickListener {
                        longToast("I'm pressed for the item at position => $position")
                        true    
                }       
        }       
    
    } 
    
    0 讨论(0)
提交回复
热议问题