AdapterView.AdapterContextMenuInfo 为空

AdapterView.AdapterContextMenuInfo is null

这是我的问题,我的架构是 class :

适配器:

片段

overrrides onContextItemSelected(MenuItem item){
    //info is null
    AdapterView.AdapterContextMenuInfo info =
        (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
}

它还调用

    registerForContextMenu(recyclerView);

顺序

  1. 我长按 NoteViewHolder,它会打开上下文菜单
  2. 我select"Delete"
  3. 使用 contextMenuInfo == null 调用 OnCreateContextMenu
  4. onSelectedContextItem 使用 item.getMenuInfo() == null
  5. 调用

如何获取非空的 menuInfo?

我应该自己创建菜单信息吗?如果是,在哪里?

PS,我看过这个post:How to create context menu for RecyclerView,我没有看到这个

的答案

PS2 我也读过这个:http://androidheight.blogspot.fr/2015/03/recyclerview-widget-example-in-android.html,对我来说 new RecyclerAdapter().info = menuInfo; 这行似乎是错误的

谢谢

您需要在 RecyclerView 的 activity 中调用 registerForContextMenu()

这是一个我认为足够干净并为此实施的解决方案。

在适配器中,我创建了一个要实现的接口(由另一个 class,例如 activity 或我的片段)。

我将接口实现传递给适配器的CTOR。它可以以不同的方式传递,这只是这里的一个选择,因为我在片段或 activity 中创建了适配器,所以无论如何我都可以立即传递接口实现。 这个接口可以有你想要的方法。

public interface  NoteListCommandListener{
    void updateList();
    void remove(Note n);
}
RVNoteAdapter(NoteListCommandListener noteListCommandListener){
    super();
    mNoteListCommandListener = noteListCommandListener;
}

我修改了 onBindViewHolder 方法,将接口实现从适配器传递给每个视图持有者。

@Override
public void onBindViewHolder(NoteViewHolder personViewHolder, int i) {

    String name = notes.get(i).name;
    personViewHolder.noteName.setText(name);
    personViewHolder.noteListCommandListener= mNoteListCommandListener;
}

然后在视图持有者 CTOR 中,我使用 setOnCreateContextMenuListener,我在本地指定 class 因为当我调用 setOnMenuItemClickListener 时我仍然可以访问 noteListCommandListener 并且我可以直接调用它的任何函数。

public static class NoteViewHolder extends RecyclerView.ViewHolder
{
    TextView noteName;
    NoteListCommandListener noteListCommandListener;
    public NoteViewHolder(View itemView) {

        super(itemView);
        noteName = (TextView)itemView.findViewById(R.id.note_name);
        itemView.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
            @Override
            public void onCreateContextMenu(ContextMenu contextMenu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) {
                contextMenu.setHeaderTitle("Select The Action");
                contextMenu.add(0,42,0,"Delete Note").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem menuItem) {
                        noteListCommandListener.remove(n);
                        return true;
                    }
                });


            }
        });


        }


}

优点是view holder的整个上下文菜单都在view holder中编码,很简单。 如果您需要动态更改上下文菜单(不是我的情况),则它的缺点是不能很好地分离。如果这样做,您可以避免在本地定义 2 class 并通过在 CTORS 中传递适当的参数来传递 class 在该范围之外定义。

谢谢大家的指教