RecyclerView getMenuInfo始终为null

时间:2016-04-30 18:44:32

标签: android android-recyclerview contextmenu

我尝试为我的RecyclerView设置一个ContextMenu,当我完成longClick这项工作时,但当我试图在getMenuInfo访问时,即使在onCreateContextMenu

我已经尝试过这个链接:

对于MainActivity中的registerForContextMenu

@Bind(R.id.rvFeed)
RecyclerView         feed;
------
feed.setAdapter(adapter);
registerForContextMenu(feed);

我的onCreateContextMenu实施:

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
    if (info == null) {
        Log.d(TAG, "info == null");
    }
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main_menu_drawer, menu);
}

onContextItemSelected

@Override
public boolean onContextItemSelected(MenuItem item) {
    AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
    if (info == null) {
        Log.d(TAG, "info == null");
    }
    return super.onContextItemSelected(item);
}

main_menu_drawer

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_drawer_delete"
        android:title="@string/menufeed_menu_asread" />
</menu>

2 个答案:

答案 0 :(得分:1)

根据您的问题,我了解您希望在回收站视图中使用浮动上下文菜单。请遵循此method

现在,既然你没有说明你想要menuinfo的原因,那么我将举一个你希望项目位置删除视图的例子。

因为您的代码与this类似。

所有解释均参考第一行中的链接。

当你长时间点击视图/项目时,会调用onCreateContextMenu(...)并发送视图(长按),将视图复制到视图持有者的临时变量中。

主要部分: 你如何确定哪个列表项/视图是这样的? 为此,您可以在onBindHolder中为每个视图设置一个标记。

  

使用位置作为标记(尽管不是必需的)。

然后在我们在ViewHolder类中保存的临时视图上调用getTag()。

示例实施:

 @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {

        holder.tvName.setText(holder.name);
        holder.tvName.setTag(position);

    }
    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener,
                MenuItem.OnMenuItemClickListener {
            private final TextView tvName;
            private static final int DEL_ITEM_ID = 9116;
            private View toRemoveView;
            private String name;
            public ViewHolder(View view) {
                super(view);
                tvName = (TextView) view.findViewById(R.id.list_item);
                view.setOnCreateContextMenuListener(this);


   }

        @Override
        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
            menu.setHeaderTitle("Select action:");
            toRemoveView=v;
            MenuItem item = menu.add(0, DEL_ITEM_ID,100,"Delete");
            item.setOnMenuItemClickListener(this);
        }

        @Override
        public boolean onMenuItemClick(MenuItem item) {
            switch (item.getItemId()) {
                case DEL_ITEM_ID:
                    deleteRecord((Integer) toRemoveView.getTag());
                    //notifyItemRemoved(...) -- your wish
                    return true;
                default:
                    return false;
            }
        }
  

警告我在项目数量只有2并且删除了一个(工作正常)时对此进行了测试。我没有在列表滚动时测试它。但是,由于每个项目都分配了一个唯一的标记(位置),因此不应该造成任何麻烦。

我想我已经让自己清楚了。 如果我在某处错了,请纠正我。

<强>更新 你也可以在viewholder类中调用getAdapterPosition()。我还没试过。

答案 1 :(得分:1)

对于我的情况,dark_escape建议不起作用,但正如他建议getAdapterPosition()可以工作,并且对我来说完美。这里是一个例子,我将它用于文件管理器进行删除。 (继续他的想法,他只是假设需要menueinfo来移除物品或从物品中获取信息)

在ViewHolder中扩展View.OnCreateContextMenuListener,我们覆盖:

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    menu.setHeaderTitle("Select The Action");

    int indexOfItemClickedInList = getAdapterPosition();

    menu.add(0, indexOfItemClickedInList, 0, R.string.ContextMenuItemTitleTextDELETE);
    // keep adding menu items with that AdapterPosition
    // if u need it for the selected actions
}

我已经从AndroidStuido中的模板创建了MasterDetail。因此,我的ViewHolder在SimpleItemRecyclerViewAdapter中声明,并且适配器在Activity中声明,我现在覆盖它:

@Override
public boolean onContextItemSelected(MenuItem item) {
    int itemid = item.getItemId(); // index of Item clicked in the List
    String title = item.getTitle().toString(); // contextmenu choice text

    // Here I use ifs on the title to see wich item has been chosen
    if (title.equals(getApplicationContext().getResources().getString(R.string.ContextMenuItemTitleTextDELETE))) {
        // Do things that require the item id - like moving photos...
        // in this case I needed it to delete files
        String fnameToDelete = DummyContent.ITEMS.get(itemid).fname;
        MyStaticIOHelperClass.DeleteFileFromDisk(fnameToDelete , this);

        // After actually removing the file 
        // I needed to cleanup the Data used by the recycler
        DummyContent.ITEM_MAP.remove(DummyContent.ITEMS.get(itemid).fname);
        DummyContent.ITEMS.remove(itemid);

        // Rebuild the recycler view after this 
        // I basically call .setAdapter() on the recycler view in there
        // creating the adapter new like I do in onCreate of this Activity
        BuildRecycler();
    }
}


private void BuildRecycler(){
    View recyclerView = findViewById(R.id.trail_list);
    assert recyclerView != null;
    setupRecyclerView((RecyclerView) recyclerView);
}

DummyContent是Template提供的静态类。 它保存/构建用于填充回收站视图的数据。