recyclerview item for desplegable crear context android contextmenu android-recyclerview

android - item - Cómo crear un menú contextual para RecyclerView



dropdown recyclerview android (16)

Hola chicos, no se puede implementar directamente este método como onClickListener , OnContextMenuListener , etc. porque RecycleView amplía android.view.ViewGroup, por lo que no podemos usar directamente este método. podemos implementar estos métodos en la clase de adaptador ViewHolder . podemos usar el menú contextual en RecycleView así

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

Ahora seguimos el mismo procedimiento mientras implementamos el menú contextual.

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

si tiene alguna dificultad, pregunte en el comentario. Orgulloso de ser androide :)

¿Cómo implemento el menú de contexto para RecyclerView? Aparentemente, llamar a registerForContextMenu(recyclerView) no funciona. Lo estoy llamando de un fragmento. ¿Alguien tuvo éxito al implementar esto?


Ampliando un poco algunas de las respuestas anteriores, si desea evitar definir manualmente el menú en su código en Adapter / ViewHolder, puede usar un PopupMenu e inflar las opciones de menú de un archivo de recursos menu.xml estándar.

El siguiente ejemplo muestra esto, incluida la capacidad de pasar a un oyente que puede implementar en su Fragmento / Actividad para responder a los clics del menú contextual.

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> { private List<CustomObject> objects; private OnItemSelectedListener listener; private final boolean withContextMenu; class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnCreateContextMenuListener, PopupMenu.OnMenuItemClickListener { @BindView(R.id.custom_name) TextView name; @BindView(R.id.custom_value) TextView value; ViewHolder(View view) { super(view); ButterKnife.bind(this, view); view.setOnClickListener(this); if (withContextMenu) { view.setOnCreateContextMenuListener(this); } } @Override public void onClick(View v) { int position = getAdapterPosition(); if (listener != null) { listener.onCustomerSelected(objects.get(position)); } } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { PopupMenu popup = new PopupMenu(v.getContext(), v); popup.getMenuInflater().inflate(R.menu.custom_menu, popup.getMenu()); popup.setOnMenuItemClickListener(this); popup.show(); } @Override public boolean onMenuItemClick(MenuItem item) { if (listener != null) { CustomObject object = objects.get(getAdapterPosition()); listener.onCustomerMenuAction(object, item); } return false; } } public CustomerAdapter(List<CustomObject> objects, OnItemSelectedListener listener, boolean withContextMenu) { this.listener = listener; this.objects = objects; this.withContextMenu = withContextMenu; } public interface OnItemSelectedListener { void onSelected(CustomObject object); void onMenuAction(CustomObject object, MenuItem item); } @Override public CustomerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.snippet_custom_object_line, parent, false); return new ViewHolder(v); } @Override public void onBindViewHolder(CustomAdapter.ViewHolder holder, int position) { CustomObject object = objects.get(position); holder.name.setText(object.getName()); holder.value.setText(object.getValue()); } @Override public int getItemCount() { return objects.size(); } }

Completa la esencia aquí https://gist.github.com/brettwold/45039b7f02ce752ae0d32522a8e2ad9c


En mi caso, tuve que usar datos de mi fragmento en el método onContextItemSelected() . La solución a la que terminé fue pasar una instancia del fragmento en mi adaptador y registrar el elemento de la vista en el titular de la vista:

@Override public void onBindViewHolder(final MyListAdapter.ViewHolder viewHolder, int position) { final Object rowObject = myListItems.get(position); // Do your data binding here viewHolder.itemView.setTag(position); fragment.registerForContextMenu(viewHolder.itemView); }

Luego, en onCreateContextMenu() puede guardar el índice en una variable local:

selectedViewIndex = (int)v.getTag();

y recuperarlo en onContextItemSelected()


Gracias por la información y los comentarios. Pude lograr ContextMenu para los artículos en Recyclerview .

Aquí esta lo que hice

en el método Fragment''s onViewCreated o en el método Activity onCreate :

registerForContextMenu(mRecyclerView);

Luego, en adaptador agregar

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

hacer que la clase ViewHolder implemente 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 método onBindViewHolder agrega OnLongClickListener en el holder.itemView para capturar la posición antes de que se cargue el menú contextual:

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

Luego, en onViewRecycled elimine el Listener para que no haya problemas de referencia. (puede no ser requerido).

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

Finalmente, en el Fragmento / Actividad se anula el onContextItemSelected como en:

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


He combinado mi solución con la solución de @Hardik Shah:

En la actividad que tengo:

@Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); if (v.getId() == R.id.rvQuests) { getMenuInflater().inflate(R.menu.list_menu, menu); } }

En el adaptador tengo:

private MainActivity context; private int position; public int getPosition() { return position; } public void setPosition(int position) { this.position = position; } public QuestsAdapter(MainActivity context, List<Quest> objects) { this.context = context; this.quests.addAll(objects); } public class QuestViewHolder extends RecyclerView.ViewHolder { private QuestItemBinding questItemBinding; public QuestViewHolder(View v) { super(v); questItemBinding = DataBindingUtil.bind(v); v.setOnCreateContextMenuListener(context); } } @Override public void onBindViewHolder(final QuestViewHolder holder, int position) { Quest quest = quests.get(position); holder.questItemBinding.setQuest(quest); holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { setPosition(holder.getAdapterPosition()); return false; } }); } @Override public void onViewRecycled(QuestViewHolder holder) { holder.itemView.setOnLongClickListener(null); super.onViewRecycled(holder); }

En fragmento tengo:

@Override public boolean onContextItemSelected(MenuItem item) { int position = ((QuestsAdapter) questsList.getAdapter()).getPosition(); switch (item.getItemId()) { case R.id.menu_delete: Quest quest = questsAdapter.getItem(position); App.getQuestManager().deleteQuest(quest); questsAdapter.remove(quest); checkEmptyList(); return true; default: return super.onContextItemSelected(item); } }


He estado luchando con esto porque Android no maneja esto muy bien para mí en RecyclerView, que funcionaba muy bien para ListView.

La pieza más difícil es que la pieza ContextMenuInfo está incrustada dentro de una Vista, que no puede adjuntar fácilmente que no sea anular la Vista.

Por lo tanto, necesitará un contenedor que lo ayude a entregar la información de posición a la Actividad.

public class RecyclerContextMenuInfoWrapperView extends FrameLayout { private RecyclerView.ViewHolder mHolder; private final View mView; public RecyclerContextMenuInfoWrapperView(View view) { super(view.getContext()); setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); mView = view; addView(mView); } public void setHolder(RecyclerView.ViewHolder holder) { mHolder = holder; } @Override protected ContextMenu.ContextMenuInfo getContextMenuInfo() { return new RecyclerContextMenuInfo(mHolder.getPosition(), mHolder.getItemId()); } public static 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; }

}

Luego, en tu RecyclerAdapter, cuando crees ViewHolders, necesitas configurar el Wrapper como la vista raíz y registrar el menú contextual en cada vista.

public static class AdapterViewHolder extends RecyclerView.ViewHolder { public AdapterViewHolder( View originalView) { super(new RecyclerContextMenuInfoWrapperView(originalView); ((RecyclerContextMenuInfoWrapperView)itemView).setHolder(this); yourActivity.registerForContextMenu(itemView); itemView.setOnCreateContextMenuListener(yourListener); }

}

Y, por último, en su actividad, podrá hacer lo que generalmente hace:

@Override public boolean onContextItemSelected(MenuItem item) { int position = ((RecyclerContextMenuInfoWrapperView.RecyclerContextMenuInfo)item.getMenuInfo()).position; // do whatever you need as now you have access to position and id and everything


Hola chicos, salí con una alternativa que funciona para mí. Acabo de registrar mi itemView con registerContextMenu y ViewHolder Constructor, también configuré onLongClikcListener en la misma Vista. En la implementación onLongClick (View v), simplemente obtengo la posición cliqueada con getLayoutPosition () y guardo en una variable de instancia (creé una clase para representar estos datos, al igual que se espera que funcione ContextMenuInfo), pero lo más importante es hacer seguro que devuelve falso en este método. Todo lo que tienes que hacer ahora está en ti en onContextItemSelected (elemento MenuItem), lee los datos que almacenas en tu variable de instancia y, si es válido, sigues con tus acciones. Aquí hay un fragmento.

public MyViewHolder(View itemView){ super(itemView); registerForContextMenu(itemView); itemView.setOnLongClickListener(this); }

Hago que ViewHolder implemente OnLongClickListener, pero puedes hacerlo de la manera que prefieras.

@Override public boolean onLongClick(View v){ mCurrentLongItem = new ListItemInfo(v.getId(), getLayoutPosition()); return false; // REMEMBER TO RETURN FALSE. }

También puede configurar esto en el adaptador o en otra vista que tenga en ViewHolder (es decir, una vista de texto). Lo importante es la implementación onLongClik ().

@Override public boolean onContextItemSelected(MenuItem item) { switch (item.getItemId()){ case R.id.client_edit_context_menu: if(mCurrentLongItem != null){ int position = mCurrentLongItem.position; //TAKE SOME ACTIONS. mCurrentLongItem = null; } return true; } return super.onContextItemSelected(item); }

La mejor parte es que aún puede procesar el evento LongClick devolviendo verdadero en los casos que desee y el conextMenu no se mostrará.

Este método funciona porque registerForContextView hace que la vista LongClickable, y cuando es hora de procesar el ContextMenu, el sistema llama a performLongClick, que primero llama a una implementación onLongClick, y si devuelve false, entonces llama a showContextMenu.


La respuesta actual no es correcta. Aquí hay una implementación que funciona:

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; } }

En tu Fragmento (o Actividad):

@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 }

Y finalmente, en su ViewHolder:

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


La respuesta de @ Renaud funcionó para mí, pero primero requirió varias correcciones de código. Es como si hubiera publicado fragmentos de varias iteraciones diferentes de su código. Los cambios que deben hacerse son:

  • RecyclerContextMenuInfo y RecyclerViewContextMenuInfo son la misma clase. Elija un nombre y quédese con él.
  • El ViewHolder debe implementar View.OnLongClickListener , y recuerda llamar a setOnLongClickListener() en el elemento en el constructor.
  • En el oyente onLongClick() , getView().showContextMenu() es completamente incorrecto. Debe llamar a showContextMenuForChild() en su ContextMenuRecyclerView ; de lo contrario, el ContextMenuInfo que obtenga onCreateContextMenu() y onContextItemSelected() será nulo.

Mi código editado a continuación:

ContextMenuRecyclerView:

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; } }

En tu fragmento:

@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 here // If you want the position of the item for which we''re creating the context menu (perhaps to add a header or something): int itemIndex = ((ContextMenuRecyclerView.RecyclerViewContextMenuInfo) menuInfo).position; } @Override public boolean onContextItemSelected(MenuItem item) { ContextMenuRecyclerView.RecyclerViewContextMenuInfo info = (ContextMenuRecyclerView.RecyclerViewContextMenuInfo) item.getMenuInfo(); // handle menu here - get item index or ID from info return super.onContextItemSelected(item); }

En su ViewHolder:

class MyViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener { public MyViewHolder( View itemView ) { super( itemView ); itemView.setOnLongClickListener( this ); } @Override public boolean onLongClick() { recyclerView.showContextMenuForChild( v ); return true; } }

Además, asegúrese de reemplazar RecyclerView con ContextMenuRecyclerView en su diseño.


La respuesta de Prabhakar es correcta, pero no explicó cómo obtener datos relacionados con el elemento presionado cuando se selecciona un elemento de menú contextual. Podemos usar la onContextItemSelected llamada onContextItemSelected , pero ContextMenuInfo no está disponible ( null ) en este caso (si el método getContextMenuInfo() no se reemplaza para una vista presionada). Entonces, la solución más simple es agregar OnMenuItemClickListener directamente al MenuItem .

private class ViewHolder extends RecyclerView.ViewHolder { private final TextView mTitleTextView; private MyItemData mData; public ViewHolder(View view) { super(view); mTitleTextView = (TextView)view.findViewById(R.id.title); view.setOnCreateContextMenuListener(mOnCreateContextMenuListener); } public void bind(@NonNull MyItemData data) { mData = data; String title = mData.getTitle(); mTitleTextView.setText(title); } private final View.OnCreateContextMenuListener mOnCreateContextMenuListener = new View.OnCreateContextMenuListener() { @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { if (mData!= null) { MenuItem myActionItem = menu.add("My Context Action"); myActionItem.setOnMenuItemClickListener(mOnMyActionClickListener); } } }; private final MenuItem.OnMenuItemClickListener mOnMyActionClickListener = new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { //todo: process item click, mData is available here!!! return true; } }; }


Lo mejor fue usar el menú Contexto con la vista de reciclador si realiza una vista de reciclador personalizada y reemplaza el método getContextMenuInfo() y devuelve su propia instancia de objeto de información de menú contextual para que pueda recuperar posiciones cuando se creó y cuando se hace clic en el menú :

@Override protected ContextMenu.ContextMenuInfo getContextMenuInfo() { return mContextMenuInfo; }

Echa un vistazo a esta esencia que he creado:

https://gist.github.com/resengupta/2b2e26c949b28f8973e5


Ok, basado en la respuesta de @Flexo, pondré mPosition en orden ...

protected class ExampleViewHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener { int mPosition; public KWViewHolder(View itemView) { super(itemView); itemView.setOnCreateContextMenuListener(this); } public void setPosition(int position) { mPosition = position; } @Override public void onCreateContextMenu(ContextMenu contextMenu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) { contextMenu.setHeaderTitle(R.string.menu_title_context); contextMenu.add(0, R.id.menu_delete, mPosition, R.string.delete); } }

luego en onContextItemSelected que uso

item.getOrder()

Y todo funciona bien, obtengo la posición de la matriz fácilmente


Prueba esto para View un elemento en recycleView

.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() { @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { menu.add("delete").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { //do what u want return true; } }); } });

Puede usarlo para configurar los datos en un elemento ViewHolder


Puede pasar OnCreateContextMenuListener a ViewHolder en bind. Este oyente puede crear un menú personalizado para cada elemento de datos. Simplemente agregue setOnCreateContextMenuListener en su ViewHolder y llámelo durante el enlace.

public static class ItemViewHolder extends RecyclerView.ViewHolder { public ItemViewHolder(View itemView) { super(itemView); } void setOnCreateContextMenuListener(View.OnCreateContextMenuListener listener) { itemView.setOnCreateContextMenuListener(listener); }

}

En adaptador:

@Override public void onBindViewHolder(ItemViewHolder viewHolder, int position) { final MyObject myObject = mData.get(position); viewHolder.setOnCreateContextMenuListener(new OnCreateContextMenuListener(){ @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { switch (myObject.getMenuVariant() { case MNU_VARIANT_1: menu.add(Menu.NONE, CTX_MNU_1, Menu.NONE,R.string.ctx_menu_item_1); menu.add(Menu.NONE, CTX_MNU_2,Menu.NONE, R.string.ctx_menu_item_2); break; case MNU_VARIANT_2: menu.add(Menu.NONE, CTX_MNU_3,Menu.NONE, R.string.ctx_menu_item_3); break; default: menu.add(Menu.NONE, CTX_MNU_4, Menu.NONE, R.string.ctx_menu_item_4); } } }); }


Quizás llegue tarde a la fiesta, pero tengo una solución de trabajo . He hecho una esencia para eso.

Agregar menú contextual a RecyclerView

ActivityName.java

//Import Statements public class ActivityName extends AppCompatActivity { private RecyclerView mRecyclerView; private RecyclerView.Adapter mAdapter; private RecyclerView.LayoutManager mLayoutManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_view_birthdays); //Recycle View mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view); mLayoutManager = new LinearLayoutManager(getApplicationContext()); mRecyclerView.setLayoutManager(mLayoutManager); mAdapter = new BirthdaysListAdapter(data, this); mRecyclerView.setAdapter(mAdapter); }

RecyclerAdapter.java

//Import Statements public class BirthdaysListAdapter extends RecyclerView.Adapter<BirthdaysListAdapter.ViewHolder> { static Context ctx; private List<typeOfData> Data; public BirthdaysListAdapter(List<typeOfData> list, Context context) { Data = list; this.ctx = context; } BirthdaysListAdapter() { } public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener { public TextView name; public TextView Birthday; public ImageView colorAlphabet; public TextView textInImg; public ViewHolder(View v) { super(v); name = (TextView) v.findViewById(R.id.name); Birthday = (TextView) v.findViewById(R.id.Birthday); colorAlphabet = (ImageView) v.findViewById(R.id.colorAlphabet); textInImg = (TextView) v.findViewById(R.id.textInImg); v.setOnCreateContextMenuListener(this); //REGISTER ONCREATE MENU LISTENER } @Override public void onCreateContextMenu(ContextMenu menu, View v //CREATE MENU BY THIS METHOD ContextMenu.ContextMenuInfo menuInfo) { new BirthdaysListAdapter().info = (AdapterView.AdapterContextMenuInfo) menuInfo; MenuItem Edit = menu.add(Menu.NONE, 1, 1, "Edit"); MenuItem Delete = menu.add(Menu.NONE, 2, 2, "Delete"); Edit.setOnMenuItemClickListener(onEditMenu); Delete.setOnMenuItemClickListener(onEditMenu); } //ADD AN ONMENUITEM LISTENER TO EXECUTE COMMANDS ONCLICK OF CONTEXT MENU TASK private final MenuItem.OnMenuItemClickListener onEditMenu = new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { DBHandler dbHandler = new DBHandler(ctx); List<WishMen> data = dbHandler.getWishmen(); switch (item.getItemId()) { case 1: //Do stuff break; case 2: //Do stuff break; } return true; } }; } public List<ViewBirthdayModel> getData() { return Data; } @Override public long getItemId(int position) { return super.getItemId(position); } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_view_birthdays, parent, false); ViewHolder vh = new ViewHolder(view); return vh; } @Override public void onBindViewHolder(final ViewHolder holder, int position) { holder.name.setText(Data.get(position).getMan().getName()); holder.Birthday.setText(Data.get(position).getMan().getBday()); holder.colorAlphabet.setBackgroundColor(Color.parseColor(Data.get(position).getColor())); holder.textInImg.setText(String.valueOf(Data.get(position).getMan().getName().toUpperCase().charAt(0))); } @Override public int getItemCount() { return Data.size(); } private int position; public int getPosition() { return position; } public void setPosition(int position) { this.position = position; } }


He estado usando esta solución por un tiempo y he trabajado bastante bien para mí.

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; } }

Ahora en tu fragmento o Actividad implementa los siguientes métodos.

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

Finalmente Registrarse para el contextoMenú en la revista del reciclador

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

¡Eso debería funcionar!