How to Create Context Menu for Recyclerview

How to create context menu for RecyclerView

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.

@Override
public 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.

how to use context menu on recyclerview item provided by firebaseui

I've resolved this problem by use this solution in this post:
How to create context menu for recycleview

Here is my code:

MessageViewHolder Class:

public static class MessageViewHolder extends RecyclerView.ViewHolder  implements View.OnCreateContextMenuListener {
public TextView tvMessage;
public TextView tvDateSending;
public CircleImageView ivMessenger;
public LinearLayout linearLayout;

public MessageViewHolder(View v) {
super(v);
tvMessage = (TextView) itemView.findViewById(R.id.tvMessage);
tvDateSending = (TextView) itemView.findViewById(R.id.tvDateSending);
ivMessenger = (CircleImageView) itemView.findViewById(R.id.ivMessenger);
linearLayout= (LinearLayout) itemView.findViewById(R.id.llOneToOneChat);
v.setOnCreateContextMenuListener(this);

}
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
menu.add(0,1 , 0, "Edit");
menu.add(0, COPY, 0, "Copy");
menu.add(0, DELETE, 0, "Delete");
}

}

MessageAdapter class:

public class MessageAdapter extends FirebaseRecyclerAdapter<Message, MessageViewHolder>{

private Context context;
private long prevMessageTime=0;
public int position;

public int getPosition() {
return position;
}

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

public MessageAdapter(Class<Message> modelClass, int modelLayout, Class<MessageViewHolder> viewHolderClass, DatabaseReference ref, Context context) {
super(modelClass, modelLayout, viewHolderClass, ref);
this.context = context;
}

@Override
protected void populateViewHolder(MessageViewHolder viewHolder, Message message, final int position) {
//do something
viewHolder.tvMessage.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
setPosition(position);
return false;
}

});
}
}

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

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

break;
case 2:
// copy message
if (position!= -1){
ClipboardManager clipboard = (ClipboardManager) OneToOneConversationActivity.this.getSystemService(Context.CLIPBOARD_SERVICE);
String text = messageAdapter.getItem(position).getMessage();
ClipData clip = android.content.ClipData.newPlainText("Copied Text", text);
clipboard.setPrimaryClip(clip);

}

break;
case 3:
//delete message
if (position!= -1)
messageAdapter.getRef(position).removeValue();
break;
}
return super.onContextItemSelected(item);
}

Hope it works for you!

Create Options Menu for RecyclerView-Item

I found out that the only Menu, that looks like the Menu above is the PopupMenu.

So in onClick:

@Override
public void onClick(View view, int position, MotionEvent e) {
ImageButton btnMore = (ImageButton) view.findViewById(R.id.item_song_btnMore);

if (RecyclerViewOnTouchListener.isViewClicked(btnMore, e)) {
PopupMenu popupMenu = new PopupMenu(view.getContext(), btnMore);

getActivity().getMenuInflater().inflate(R.menu.menu_song, popupMenu.getMenu());

popupMenu.show();

//The following is only needed if you want to force a horizontal offset like margin_right to the PopupMenu
try {
Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
fMenuHelper.setAccessible(true);
Object oMenuHelper = fMenuHelper.get(popupMenu);

Class[] argTypes = new Class[] {int.class};

Field fListPopup = oMenuHelper.getClass().getDeclaredField("mPopup");
fListPopup.setAccessible(true);
Object oListPopup = fListPopup.get(oMenuHelper);
Class clListPopup = oListPopup.getClass();

int iWidth = (int) clListPopup.getDeclaredMethod("getWidth").invoke(oListPopup);

clListPopup.getDeclaredMethod("setHorizontalOffset", argTypes).invoke(oListPopup, -iWidth);

clListPopup.getDeclaredMethod("show").invoke(oListPopup);
}
catch (NoSuchFieldException nsfe) {
nsfe.printStackTrace();
}
catch (NoSuchMethodException nsme) {
nsme.printStackTrace();
}
catch (InvocationTargetException ite) {
ite.printStackTrace();
}
catch (IllegalAccessException iae) {
iae.printStackTrace();
}
}
else {
MusicPlayer.playSong(position);
}
}

You have to make your onClick-Method pass the MotionEvent and finally implement the Method isViewClicked in your RecyclerViewOnTouchListener:

public static boolean isViewClicked(View view, MotionEvent e) {
Rect rect = new Rect();

view.getGlobalVisibleRect(rect);

return rect.contains((int) e.getRawX(), (int) e.getRawY());
}

How to have a ContextMenu when the recyclerview item is set onLongClickListener

Based on my experience I do not need to have setOnLongClickListener to make the context menu appear, View.OnCreateContextMenuListener will do that for me.

Here's my working code:

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

public TextView name;

public ViewHolder(View itemLayoutView) {
super(itemLayoutView);
name = (TextView) itemLayoutView.findViewById(R.id.rvname);
itemLayoutView.setOnClickListener(this);
itemLayoutView.setOnCreateContextMenuListener(this);
}

@Override
public void onClick(View v) {
String location = name.getText().toString();
Intent goFlip = new Intent(RecyclerAdapter.context, FlipActivity.class);
Bundle bundle = new Bundle();
bundle.putString("name", location);
bundle.putInt("pos", getAdapterPosition());
goFlip.putExtras(bundle);
context.startActivity(goFlip);
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
menu.setHeaderTitle("Select Action");
MenuItem edit = menu.add(Menu.NONE,1,1,"Edit");
MenuItem delete = menu.add(Menu.NONE,2,2,"Delete");

edit.setOnMenuItemClickListener(onChange);
delete.setOnMenuItemClickListener(onChange);
}
private final MenuItem.OnMenuItemClickListener onChange = new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()){
case 1:
Toast.makeText(context,"Edit",Toast.LENGTH_LONG).show();
return true;
case 2:
Toast.makeText(context,"Delete",Toast.LENGTH_LONG).show();
return true;
}
return false;
}
};
}

I also want to share the link that I found to make this work:
https://gist.github.com/gauravat16/e8e03496a4056829e65dede3c236da28

Android - Long Click on RecyclerView item and ContextMenu

What you need there is to show Dialog with list inside. Like that:

    itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
final CharSequence[] items = {"Supprimer", "etc", "etc1"};

AlertDialog.Builder builder = new AlertDialog.Builder(mContext);

builder.setTitle("Select The Action");
builder.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int item) {
}
});
builder.show();
return true;
}
});

ContextMenu with RecyclerView and Cardviews in it

If you dont set a long click listener the menu will open on long click event with:

public static class MyViewHolder extends RecyclerView.ViewHolder
implements View.OnCreateContextMenuListener, View.OnClickListener,
MenuItem.OnMenuItemClickListener {

MyViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
itemView.setOnCreateContextMenuListener(this);
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
MenuItem myActionItem = menu.add("Some menu item");
myActionItem.setOnMenuItemClickListener(this);
}

@Override
public boolean onMenuItemClick(MenuItem item) {
// Menu Item Clicked!
return true;
}
}


Related Topics



Leave a reply



Submit