为RecycleView添加ContextMenu支持

最近要实现如下的长按删除,首先想到的是用PopupWindow,可是又想起上下文菜单,觉得可以尝试下,使用的时候也是各种搜索,觉得有必要记录下。

为RecycleView添加ContextMenu支持_第1张图片
Paste_Image.png

设置长按弹出菜单事件

        
        //好像不注册 ContextMenu ,也可以直接长按出来
        //registerForContextMenu(recyclerView);
        //设置菜单弹出事件
        recyclerView.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
            @Override
            public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
                menu.add(0, ContextMenu.FIRST+1, 0, "删除");
            }
        });

设置菜单的点击事件,重写onContextItemSelected

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        if (item.getItemId() == ContextMenu.FIRST + 1) {
            AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();

            //删除
            Log.i(TAG, "onContextItemSelected: position="+menuInfo.position);
            cancelFavorite(menuInfo.position);
        }
        return super.onContextItemSelected(item);
    }

在这里,应该也会迷惑,怎么获取item的 position 位置尼?怎么知道我点击的是哪一个,我要根据这个去获取对应的数据。而方法中的AdapterView.AdapterContextMenuInfo 又是什么鬼?

一、结构
public static class AdapterContextMenuInfo extends Object

implements ContextMenu.ContextMenuInfo

        

java.lang.Object

android.widget.AdapterView.AdapterContextMenuInfo

 
 

  二、概述

当显示 AdapterView 的上下文菜单时,为 onCreateContextMenu(ContextMenu, View, ContextMenuInfo) 回调函数提供的额外的菜单信息。
 

 

  三、字段

  public long id

  用于显示上下文菜单的子视图的行 ID。
 
  public int position

  用于显示上下文菜单的子视图在适配器中的位置。
 
  public View targetView

  用于显示上下文菜单的子视图。也是 AdapterView 的子视图之一。
 
  四、构造函数

  public AdapterView.AdapterContextMenuInfo (View targetView, int position, long id)

在Listview中是默认提供了这个的,但是RecycleView没有实现这个,需要我们自己实现。

public class RecyclerViewImplementsContextMenu extends RecyclerView {
    private AdapterView.AdapterContextMenuInfo contextMenuInfo;
    public RecyclerViewImplementsContextMenu(Context context) {
        super(context);
    }

    public RecyclerViewImplementsContextMenu(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public RecyclerViewImplementsContextMenu(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public AdapterView.AdapterContextMenuInfo getContextMenuInfo() {
        return contextMenuInfo;
    }

    @Override
    public boolean showContextMenuForChild(View originalView) {
        int position = getChildAdapterPosition(originalView);
        long longId = getChildItemId(originalView);
        contextMenuInfo = new AdapterView.AdapterContextMenuInfo(originalView, position, longId);
        return super.showContextMenuForChild(originalView);
    }

}

重写getContextMenuInfo 和 showContextMenuForChild。

这里沿用了Listview中的数据结构,当然,也可以自定义ContextMenuInfo的数据内容,类似AdapterView.AdapterContextMenuInfo 一样实现ContextMenu.ContextMenuInfo接口

    public static class AdapterContextMenuInfo implements ContextMenu.ContextMenuInfo {

        public AdapterContextMenuInfo(View targetView, int position, long id) {
            this.targetView = targetView;
            this.position = position;
            this.id = id;
        }

        /**
         * The child view for which the context menu is being displayed. This
         * will be one of the children of this AdapterView.
         */
        public View targetView;

        /**
         * The position in the adapter for which the context menu is being
         * displayed.
         */
        public int position;

        /**
         * The row id of the item for which the context menu is being displayed.
         */
        public long id;
    }

也可以参考如下两篇文章的实现

http://stackoverflow.com/questions/26466877/how-to-create-context-menu-for-recyclerview

http://www.jianshu.com/p/18633dbfee6e

你可能感兴趣的:(为RecycleView添加ContextMenu支持)