现在RecyclerView
都使用的相对频繁了,在开始使用RecyclerView
的时候,大家都应该都遇到过RecyclerView
居然没有帮我们实现Item
点击事件,顿时感觉不知所措了。查阅API
发现确实没有实现该事件,最后经过苦思冥想,还是模仿ListView
的点击事件,在onCreateViewHolder
中为每个Item
添加View
的setOnClickListener
事件,制定一个接口,在主函数中调用。瞬间解决了,一下感觉so easy
。但是这样真的好吗?我们想想一旦Item
的数量暴增这可会影响性能啊。所以我们应该想出别的方法来代替它,下面我就介绍另外一种高大上的方法来教你如何真正的为RecyclerView
的Item
添加点击事件。
原理
虽然RecyclerView
没有帮我们实现相应的点击监听事件,但我们查询它的API
会发现它有一个方法帮我们实现了,就是addOnItemTouchListener
触摸实事件,我们可以借助该监听来根据我们的触摸反应帮我们实现相同的点击事件效果。当然其中我们还要借助GestureDetectorCompat
根据触摸手势来判断是否为点击事件。
addOnItemTouchListener
为RecyclerView
添加addOnItemTouchListener
recyclerView.addOnItemTouchListener(new OnItemTouchListener(recyclerView) {
@Override
public void onItemClick(RecyclerView.ViewHolder vh) {
//item 操作
}
});
这里我们要自定义去实现RecyclerView.OnItemTouchListener
接口
实现OnItemTouchListener
在实现该接口时我们会发现有三个方法
- onTouchEvent
- onInterceptTouchEvent
- onRequestDisallowInterceptTouchEvent
第一个是处理触摸事件的,第二个是拦截触摸事件的,第三个是处理触摸冲突的。第三个这里我们用不到,不用管,至于前两个我们只要向下面我们用到的GestureDetectorCompat
传递MotionEvent
为了获取触摸的坐标,最后再定义个abstract
回调
public abstract class OnItemTouchListener implements RecyclerView.OnItemTouchListener {
private GestureDetectorCompat mGestureDetectorCompat;
private RecyclerView mRecyclerView;
public OnItemTouchListener(RecyclerView recyclerView) {
mRecyclerView = recyclerView;
mGestureDetectorCompat = new GestureDetectorCompat(mRecyclerView.getContext(),
new MyGestureListener());
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
mGestureDetectorCompat.onTouchEvent(e);
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
mGestureDetectorCompat.onTouchEvent(e);
return false;
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
public abstract void onItemClick(RecyclerView.ViewHolder vh);
GestureDetectorCompat
上面我们实例化了GestureDetectorCompat
类其中第二个参数是手势监听OnGestureListener
,但我们不需要使用它,我们可以实现它的一个简单的封装类SimpleOnGestureListener
它里面实现的都的空操作,所以我们可以自己实现特定的方法来执行我们的操作。
SimpleOnGestureListener
这里我们只要实现其中的两个方法
- onSingleTapUp
- onLongPress
其中第一个是简单的点击屏幕时执行,第二个是长按屏幕时执行。所以根据这两个方法,我们就可以从前面OnItemTouchListener
传过来的MotionEvent
获取点击的位置,根据位置使用RecyclerView
的findChildViewUnder
获取到点击的ItemView
,再通过RecyclerView
的getChildViewHolder
获取ItemView
的ViewHolder
最后再调用OnItemClick
方法。
private class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onSingleTapUp(MotionEvent e) {
View childe = mRecyclerView.findChildViewUnder(e.getX(), e.getY());
if (childe != null) {
RecyclerView.ViewHolder VH = mRecyclerView.getChildViewHolder(childe);
onItemClick(VH);
}
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View childe = mRecyclerView.findChildViewUnder(e.getX(), e.getY());
if (childe != null) {
RecyclerView.ViewHolder VH = mRecyclerView.getChildViewHolder(childe);
onItemClick(VH);
}
}
}
好了整个的实现过程就是这些,看了以后是不是感觉更高大上了呢。如果对RecyclerView
还不是很熟悉的可以先看我前面的这篇文章RecyclerView深入浅出
欢迎访问blog:https://idisfkj.github.io/
关注