RecyclerView: 如何正确的给RecycleView添加点击事件

前提:

如何为RecycleView设置点击事件,才会优雅,又不浪费内存呢?

在以前也许我会在Adapter.onBindViewHolder()为Item中相应View设置点击事件,这样是可以的,但是这样做会为“每个View(不管是当前显示在RecycleView列表中的,亦或是划出屏幕被缓存起来待下次使用的)都设置一个Listener回掉”,这样既浪费(因为没必要),又会增加内存开销(如果当前列表有1000个item,那岂不是会增加1000个Listener对象)。

究竟有没有,既优雅,又不浪费内存的做法呢?答案是有的,以下就罗列出2种比较常用的作坊,供大家参考。


1:在 Adapter.onCreateViewHolder() 中为itemView绑定点击事件

总结:onCreateViewHolder()是RecycleView初始化Item对应View的地方。之所以在这里为Item设置点击事件是因为“RdcycleView的缓存机制”,该控件的缓存机制,会做到View的复用。那些划出屏幕的View并不会被销毁掉,而是缓存起来,等待下一次加载一个新视图时,直接拿过来使用。

步骤:
1:在自定义Adapter中声明一个自定义的Interface,该接口就需要一个方法,且该方法需要把点前Itme对应的View返回。之所以要返回这个View是因为,需要通过此View从RecycleView中获取该View是列表/Adapter中的位置,然后好去从数据列表中取数据,做页面跳转等工作。

public void setClick(MyClick click){
            this.click = click;
        }

        private interface MyClick{
            void click(View v);
        }

2:在Adapter.onCreateViewHolder()中为相应View设置点击事件。并在点击事件中通过自定义Interface返回相应的Item对应的View。

@Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = this.layoutInflater.inflate(R.layout.item_sild_layout, parent, false);

            view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(click != null){
                        click.click(v);
                    }
                }
            });

            return new Holder(view, this.itemWidth, this.mTopicBg);
        }

3:需要在外部设置Adapter回调。

sildAdapter.setClick(new SildAdapter.MyClick() {
            @Override
            public void click(View v) {
                if(v != null){
                    //返回的是“当前Item对应的View在当前列表可视范围内的index”。
                    int index1 = mRecycleView.indexOfChild(v);
                    //返回的是“当前Item对应的View在Adapter数据列表中的位置”。
                    int index2 = mRecycleView.getChildAdapterPosition(v);
                    //返回的是“当前Item对应的View在整个视图列表中的index”。
                    int index3 = mRecycleView.getChildLayoutPosition(v);

                    Log.e("===111", index1 + ", " + index2 + ", " + index3 );
                }
            }
        });

2:利用RcyclerView的addOnItemTouchListener()

总结:
1:调用RecycleView.addOnItemTouchListener(),该方法会接收一个“RecyclerView.OnItemTouchListener”。
2:OnItemTouchListener内部并没有直接响应“点击”的回调方法,我们需要在其onTouchEvent()中自己来实现。
3:一般的我们可以借助“手势(GestureDetector)”来实现。在初始化手势的时候,需要接收一个“OnGestureListener”,我们只需要实现该接口就可以了。
4:如果是“点击”的话,需要重写“onSingleTapUp()”,“长按”的话需要实现“onLongPress()”。
5:点击的话,我们需要在“onSingleTapUp()”通过“RecyclerView.findChildViewUnder()”该方法需要传递一个“点击事件的x,y坐标”,RecycleView会根据点击的坐标来找到点击的那个Itme。

你可能感兴趣的:(RecyclerView: 如何正确的给RecycleView添加点击事件)