美文网首页Android LifeRecyclerViewAndroid
RecyclerView实现Item点击事件处理

RecyclerView实现Item点击事件处理

作者: ccbuluo | 来源:发表于2017-05-10 19:49 被阅读8197次

    RecyclerView并没有像ListView那样提供了OnItemClick,OnItemLongClick等事件回调接口,所以,我们需要自己去实现。

    为了后面的几种方式都可以用同一的回调接口来实现Click和LongClick事件,我们先定义一个回调事件接口。

    public static interface OnItemClickListener {
            void onItemClick(View view);
            void onItemLongClick(View view);
        }
    

    1 . 通过Adapter来处理

    在Adapter的onCreateViewHolder和onBindViewHolder函数添加如下代码

        @Override
        public ListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            ListViewHolder viewHolder = new ListViewHolder(
                    mInflater.inflate(R.layout.list_item, parent, false));
            viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mItemClickListener.onItemClick(V);
                }
            });
            viewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    mItemClickListener.onItemLongClick(v);
                    return true;
                }
            });
    
            return viewHolder;
        }
        
        @Override
        public void onBindViewHolder(ListViewHolder holder, final int position) {
            if (mData != null) {
                holder.mIndex.setText(Integer.toString(position));
                holder.mTitle.setText(mData.get(position).getTitle());
                holder.itemView.setTag(mData.get(position).getId());
            }
        }
    

    其中,mItemClickListener为注册进来的Click回调监听,一般为对应的Activity或Fragment。在onBindViewHolder中,我们对ItemView设置了Tag属性,将数据的ID设置进去,在Activity或Fragment中可以通过获取view的Tag来获取当前点击item的Id值。另外,在中,可以直接通过RecyclerView.getChildAdapterPosition获取到当前点击的Item的列表索引。

        mListAdapter.setOnViewItemClickListener(new ListAdapter.OnItemClickListener()     {
            @Override
            public void onItemClick(View view) {
                int position = mRecyclerView.getChildAdapterPosition(view);
                Toast.makeText(this, "onItemClick : " + position, Toast.LENGTH_SHORT).show();
            }
            @Override
            public void onItemLongClick(View view) {
                int position = mRecyclerView.getChildAdapterPosition(view);
                Toast.makeText(this, "onItemLongClick : " + position, Toast.LENGTH_SHORT).show();
            }
        }
    

    2 . 通过OnItemTouchListener来监听touch事件并转化为点击事件

    创建类RecyclerViewItemTouchListener继承RecyclerView.SimpleOnItemTouchListener

    public class RecyclerViewItemTouchListener extends RecyclerView.SimpleOnItemTouchListener {
        private OnItemClickListener mClickListener;
        private GestureDetectorCompat mGestureDetector;
    
        public RecyclerViewItemTouchListener(final RecyclerView recyclerView,
                                             OnItemClickListener listener) {
            this.mClickListener = listener;
            mGestureDetector = new GestureDetectorCompat(recyclerView.getContext(),
                    new GestureDetector.SimpleOnGestureListener() {
                        @Override
                        public boolean onSingleTapUp(MotionEvent e) {
                            View childView = recyclerView.findChildViewUnder(e.getX(), e.getY());
                            if (childView != null && mClickListener != null) {
                                mClickListener.onItemClick(childView);
                            }
                            return true;
                        }
    
                        @Override
                        public void onLongPress(MotionEvent e) {
                            View childView = recyclerView.findChildViewUnder(e.getX(), e.getY());
                            if (childView != null && mClickListener != null) {
                                mClickListener.onItemLongClick(childView);
                            }
                        }
                    });
        }
    
        @Override
        public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
            mGestureDetector.onTouchEvent(e);
            return false;
        }
    }
    

    在Activity或Fragment中添加OnItemTouchListener。

        mRecyclerView.addOnItemTouchListener(new RecyclerViewItemTouchListener(mRecyclerView, new RecyclerViewItemTouchListener.OnItemClickListener() {
    
            @Override
            public void onItemClick(View view) {                
            }
    
            @Override
            public void onItemLongClick(View view, int position) {
            }
            });
    

    3 . 通过OnChildAttachStateChangeListener在Item在Attach时添加点击事件
    创建RecyclerViewClickSupport类,继承RecyclerView.OnChildAttachStateChangeListener

    public class RecyclerViewClickSupport implements RecyclerView.OnChildAttachStateChangeListener {
    
        private View.OnClickListener mItemClickListener = null;
        private View.OnLongClickListener mItemLongClickListener = null;
        private RecyclerView mRecyclerView = null;
    
        public RecyclerViewClickSupport(RecyclerView view, View.OnClickListener listener,
                                        View.OnLongClickListener listener2){
            mRecyclerView = view;
            mItemClickListener = listener;
            mItemLongClickListener = listener2;
            view.addOnChildAttachStateChangeListener(this);
        }
    
        @Override
        public void onChildViewAttachedToWindow(View view) {
            if (mItemClickListener != null){
                view.setOnClickListener(mItemClickListener);
            }
            if (mItemLongClickListener != null){
                view.setOnLongClickListener(mItemLongClickListener);
            }
        }
    
        @Override
        public void onChildViewDetachedFromWindow(View view) {
    
        }
    
    }
    

    在Activity或Fragment中添加RecyclerViewClickSupport实现对RecyclerView的Item的点击事件的监听。

        mRCClickSupport = new RecyclerViewClickSupport(mRecyclerView, new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        }, new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                return false;
            }
        });
    

    以上的三种实现方式中,其中:

    • 方式二没有办法对item的子view进行事件监听,而且因为没有为item真正的添加Click事件监听,所以Item的Click按下效果出不来。
    • 方法一和方法三,更建议使用方法一,毕竟Adapter对Item的数据以及布局都有处理。
    • 方法三可以封装为独立的类,但如果要处理子view,难免还要加入布局相关的代码,这样就进一个降低了代码的耦合。

    相关文章

      网友评论

        本文标题:RecyclerView实现Item点击事件处理

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