2014-10-20 3 views
60

Как реализовать контекстное меню для RecyclerView? Очевидно, что вызов registerForContextMenu(recyclerView) не работает. Я называю это фрагментом. Удалось ли кому-нибудь добиться успеха?Как создать контекстное меню для RecyclerView

+0

Я в одной лодке. Пробовал различные оценки ListView с AdapterContextMenuInfo - но не могу получить info.position –

+0

Я думаю, что дни контекстного меню закончились. –

+4

Эй, я получил его работу;) refeerence: http://stackoverflow.com/questions/2321332/detecting-which-selected-item-in-a-listview-spawned-the-contextmenu-android - ViewHolder для меня слушатель onClick - я также сделал его OnCreateContextMenuListener. Ключом ко всему этому является то, что я понял, что только одно меню может быть открыто одновременно - поэтому для адаптера требуется только int, который должен быть указан, который был последним элементом списка RecyclerView, в котором было нажато меню ... тогда Fragment/Activity может спросите адаптер, когда он нажимает фактический пункт меню. –

ответ

60

hello guys, 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); 


    } 

Теперь мы следуем той же процедуре, а реализует контекстное меню.

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

    } 

если у вас возникли трудности с запросом в комментарии. Гордый быть андроидом :)

+4

Итак, мы реализуем уровень активности/фрагмента onContextItemSelected'on. 'getTitle' работает,' getItemId' работает, но 'getMenuInfo' поставляет null. Итак, как получить «ViewHolder»? –

+0

@MichaelSchmidt может показать ваш код, где вы реализуете информацию контекстного меню. – Prabhakar

+0

Нужно ли его реализовать отдельно? Мой 'onCreateContextMenu' точно так же, как в вашем ответе ... –

68

Спасибо за информацию и комментарии. Я смог достичь ContextMenu для предметов в Recyclerview.

Вот что я сделал

в onViewCreated метода фрагмента или onCreate метод Activity в:

registerForContextMenu(mRecyclerView); 

Затем в адаптер добавить

private int position; 

public int getPosition() { 
    return position; 
} 

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

сделать ViewHolder класс реализации 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 метод добавления OnLongClickListener на holder.itemView, чтобы захватить позицию перед загрузкой контекстное меню:

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

Затем в onViewRecycled удалить Слушатель, так что нет ссылки на вопросы. (может и не потребоваться).

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

Наконец в фрагменте/активности переопределение onContextItemSelected как в:

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

position = ((BackupRestoreListAdapter) getAdapter()). getPosition(); -> get error: метод getAdapter() не определен для типа ..., вы можете показать метод getAdapter – nguoixanh

+0

Отличное предложение, thankx. Малый: viewHolder.getPosition() устарел. Ваш совет по улучшению? – tjm1706

+8

use viewHolder.getAdapterPosition() вместо getPosition() –

0

Лучшего был использовать контекстное меню с точкой зрения ресайклера, если вы сделаете вид пользовательского ресайклера и переопределить метод getContextMenuInfo() и вернуть свой собственный экземпляр Контекстное меню инфо объекта, так что вы можете получить позиции, когда она была создана, и когда меню щелкнул:

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

Имеют смотреть на этой сути я создал:

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

17

Текущего ответ не является правильным.Вот рабочая реализация:

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

В вашем фрагменте (или активность):

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

И, наконец, в вашем ViewHolder:

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

Пожалуйста, добавьте конструктор RecyclerView, который вы должны были реализовать на вашем ContextMenuRecyclerView. Кроме того, 'getChildPosition()' устарел сейчас. Вместо этого я использовал 'getChildAdapterPosition()'. –

+0

** Примечание: ** Извините, я забыл добавить: 'getChildPosition()' устарел в 'com.android.support: recyclerview-v7: 22.0.0'. –

+1

это не работает. вы не можете получить getView(). showContextMenu() из RecyclerView.View.ViewHolder. – Mulgard

0

Я изо всех сил на это, потому что Android не справляется с этим для меня в RecyclerView, который отлично работает для ListView.

Самая сложная часть состоит в том, что часть ContextMenuInfo встроена в представление, которое вы не можете легко присоединить, кроме переопределения вида.

Для этого вам понадобится обертка, которая поможет вам доставить информацию о позиции в Activity.

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

}

Затем в RecyclerAdapter, когда вы создаете ViewHolders, вам необходимо установить Wrapper как вид корня, и зарегистрировать Контекстное на каждом представлении.

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

}

И, наконец, в вашей деятельности, вы будете в состоянии сделать то, что вы обычно делаете:

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

@ ответ Рейно работал для меня, но требуется несколько кода фиксирует первый , Это похоже на то, что он опубликовал фрагменты из нескольких разных итераций своего кода. Изменения, которые должны быть сделаны, являются:

  • RecyclerContextMenuInfo и RecyclerViewContextMenuInfo такие же класса. Выберите имя и придерживайтесь его.
  • ViewHolder должен реализовать View.OnLongClickListener и не забудьте позвонить setOnLongClickListener() по элементу в конструкторе.
  • В onLongClick() слушатель, совершенно не прав. Вы должны позвонить showContextMenuForChild() в свой ContextMenuRecyclerView, иначе ContextMenuInfo вы получите в onCreateContextMenu() и onContextItemSelected() будет null.

Мой отредактированный код ниже:

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

В вашем фрагменте:

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

В вашем 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; 
    } 
} 

Кроме того, убедитесь, что вы заменили RecyclerViewContextMenuRecyclerView в своем расположении!

+0

Спасибо @ josh2112 за то, что вы указали мне опечатки, я только что их исправил - НО в отношении вашего последнего момента вы можете заменить 'recyclerView.showContextMenuForChild (itemView);' by item item.showContextMenu() '. –

+0

Важно также: расширив RecyclerView до ContextMenuRecyclerView, не забудьте добавить ДОПОЛНИТЕЛЬНЫЕ КОНСТРУКТОРЫ, предложенные IDE. В частности, если вы не реализуете конструктор с двумя аргументами, который принимает Context и AttributeSet, Android не сможет раздуть ваш XML-макет. – lidkxx

9

Prabhakar answer верен, но он не объяснил, как получить данные, связанные с нажатым элементом, когда выбран пункт контекстного меню.Мы можем использовать обратный вызов onContextItemSelected, но ContextMenuInfo не доступен (null) в этом случае (если метод getContextMenuInfo() не переопределяется для прессованного изображения). Итак, самым простым решением является добавление OnMenuItemClickListener непосредственно к 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; 
     } 
    }; 
} 
+1

Объясните, что делает ваш фрагмент кода и как. Недостаточно только скопированного кода, даже если это стоит. – peterh

14

Попробуйте это для View пункта в 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; 
       } 
      }); 
     } 
    }); 

Вы можете использовать его с установочными данными на ViewHolder пункта

+0

Работает как шарм –

+0

Точно то, что мне нужно для контекстного меню на изображении в переработанном виде – Themos

+0

Для тех, кто смотрит на это сейчас, это работает только с API 23 и выше. – SWoo

3

Я объединил свое решение с решением от @Hardik шаха:

В деятельности у меня есть:

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

В адаптере у меня есть:

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

В фрагменте у меня есть:

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

Привет парням вышел с одной альтернативой, которая работает для меня. Я просто зарегистрирую свой itemView с помощью registerContextMenu y ViewHolder Constructor, также устанавливая onLongClikcListener в тот же вид. В реализации onLongClick (View v) я просто получаю щелкнутую позицию с помощью getLayoutPosition() и сохраняю в переменной экземпляра (я создал класс для представления этих данных, как ожидается, будет работать ContextMenuInfo), но более важно сделать обязательно верните false в этом методе. Все, что вам нужно сделать сейчас, находится в вас на onContextItemSelected (элемент MenuItem), читайте данные, которые вы храните в своей переменной экземпляра, и если они действительны, вы выполняете свои действия. Здесь это фрагмент.

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

Я делаю ViewHolder реализует OnLongClickListener, но вы можете сделать это в любом случае вы предпочитаете.

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

Вы также можете установить в адаптер, или к другому View вы имеете в ViewHolder (т.е. TextView). Важной является реализация 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); 
} 

Лучшая часть является то, что вы все еще можете обрабатывать LongClick событие возвращает истину в тех случаях, которые вы хотите, и conextMenu обыкновение появляться.

Этот метод работает, потому что registerForContextView создает View LongClickable, а когда его время обрабатывает ContextMenu, система вызывает performLongClick, который сначала вызывает реализацию onLongClick, а если он возвращает false, тогда он вызывает showContextMenu.

2

Возможно, я опаздываю на вечеринку, но у меня есть рабочее решение . Я сделал для него суть.

Add Context Menu to 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; 
    } 

} 
-1

Хорошо, основанный с @ ответ флексографской, я поставлю mPosition на заказ ...

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

затем в onContextItemSelected Я использую

item.getOrder() 

И все отлично работает я получаю позицию массива легко

1

Я использовал это решение для когда-то теперь и работал очень хорошо для меня.

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

Теперь в вашем фрагменте или деятельности реализовать следующие методы.

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

Наконец Регистрация для Контекстное на recyclerview

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

Это должно работать!

0

Развернувшись на некоторых ответах выше, если вы хотите, чтобы вы не вручную определяли меню в своем коде в Adapter/ViewHolder, вы можете использовать PopupMenu и раздувать параметры меню из стандартного ресурса menu.xml файл.

Пример ниже показывает это, в том числе возможность передать слушателю, который вы можете реализовать в своем фрагменте/мероприятии, чтобы реагировать на клики контекстного меню.

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

Полная суть здесь https://gist.github.com/brettwold/45039b7f02ce752ae0d32522a8e2ad9c

0

Вы можете передать OnCreateContextMenuListener в ViewHolder на затруднительном. Этот слушатель может создать пользовательское меню для каждого элемента данных. Просто добавьте setOnCreateContextMenuListener в свой ViewHolder и вызовите его во время привязки.

 public static class ItemViewHolder extends RecyclerView.ViewHolder 
    { 


     public ItemViewHolder(View itemView) { 
      super(itemView); 


     } 
     void setOnCreateContextMenuListener(View.OnCreateContextMenuListener listener) { 
      itemView.setOnCreateContextMenuListener(listener); 
     } 

}

В адаптере:

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

         } 
        } 

       }); 
    } 
0

В моем случае мне пришлось использовать данные из моего фрагмента в методе onContextItemSelected().Решение, которое я в конечном итоге происходит с должен был передать экземпляр фрагмента в мой адаптер и зарегистрировать элемент представления в держатель вид:

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

Тогда в onCreateContextMenu() можно сохранить индекс локальной переменной:

selectedViewIndex = (int)v.getTag();

и получить его в onContextItemSelected()