【问题标题】:RecyclerView getMenuInfo always nullRecyclerView getMenuInfo 始终为空
【发布时间】:2016-08-25 19:44:48
【问题描述】:

我尝试为我的 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>

【问题讨论】:

    标签: android android-recyclerview contextmenu


    【解决方案1】:

    dark_escape 的建议对我的情况并不适用,但正如他建议的那样 getAdapterPosition() 可以工作,并且对我来说做得很好。这是我如何将其用于文件管理器进行删除的示例。 (跟进他的想法,即他只是假设需要 menueinfo 来删除项目或从项目中获取信息)

    在扩展 View.OnCreateContextMenuListener 的 ViewHolder 中我们重写:

    @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 中声明,而 Adapter 在 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 提供的静态类。 它保存/构建用于填充回收器视图的数据。

    【讨论】:

      【解决方案2】:

      根据您的问题,我了解到您想在回收站视图中使用浮动上下文菜单。关注这个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()。不过我没试过。

      【讨论】:

        猜你喜欢
        • 2016-06-14
        • 2018-12-31
        • 2019-10-21
        • 2017-07-31
        • 2019-07-18
        • 2019-08-18
        • 2011-12-29
        • 2019-07-02
        • 2019-05-04
        相关资源
        最近更新 更多