美文网首页android技术
为RecycleView添加ContextMenu支持

为RecycleView添加ContextMenu支持

作者: 浩运 | 来源:发表于2016-12-05 18:57 被阅读1473次

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

    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

    相关文章

      网友评论

      • 嗨呀呀嗨:顶起来
      • f50c2032ffc8:文章不错,为什么没人顶起来!
        不过有一点需要补充,需要设置itemView.setLongClickable(true);
        有一点建议,使用Activity或者Fragment实现OnCreateContextMenuListener

      本文标题:为RecycleView添加ContextMenu支持

      本文链接:https://www.haomeiwen.com/subject/ykqlmttx.html