¿Cómo implemento el menú contextual para RecyclerView?
Aparentemente, llamar a registerForContextMenu(recyclerView)
no funciona. Lo estoy llamando desde un fragmento. ¿Alguien ha tenido éxito implementando esto?
Gracias por la información y los comentarios. Yo era capaz de lograr ContextMenu
para los elementos en Recyclerview
.
Esto es lo que hice
en Fragment's onViewCreated
método o Activity's onCreate
método:
registerForContextMenu(mRecyclerView);
Luego en Adapter añade
private int position;
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
haz 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);
}
}
El método onBindViewHolder
añade 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
quita el Listener para que no haya problemas de referencias. (puede que no sea necesario).
@Override
public void onViewRecycled(ViewHolder holder) {
holder.itemView.setOnLongClickListener(null);
super.onViewRecycled(holder);
}
Por último, en el fragmento / Actividad anular 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);
}
No puedes implementar directamente estos métodos como onClickListener, OnContextMenuListener etc. porque RecycleView extiende android.view.ViewGroup. Así que no podemos utilizar directamente estos métodos. Podemos implementar estos métodos en la clase adaptadora ViewHolder. Podemos utilizar el menú contextual en RecycleView de esta manera:
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 tienes alguna dificultad pregunta en comentario.
La mejor forma de utilizar el menú contextual con la vista recycler es crear una vista recycler personalizada y anular el método getContextMenuInfo()
y devolver su propia instancia del objeto de información del menú contextual para que pueda obtener las posiciones cuando se creó y cuando se hace clic en el menú:
@Override
protected ContextMenu.ContextMenuInfo getContextMenuInfo() {
return mContextMenuInfo;
}
Echa un vistazo a este gist que he creado: