我们用过RecyclerView的朋友都知道,它是不能直接设置其点击事件的,系统并没有给我们提供api,不像TextView,Button等控件,可以直接setOnClickListener(),所以退而求其次,利用曲线救国的策略,通过回调,我们一般都是在adapter里面,单独设置每一个控件的点击事件,然后回调出来,但是,这并不能复用,每次都得重新设计,所以,今天我们说一下,系统自带的可复用的RecyclerView的点击事件设置。
RecyclerView.OnItemTouchListener (接口)
我们需要新建类,实现RecyclerView.OnItemTouchListener 这个接口,重写onInterceptTouchEvent(RecyclerView rv, MotionEvent e)方法,当我们通过事件传递,捕捉到手势事件之后,将它交给手势处理的方法,就能够实现单击及长按的事件监听。
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View childView = rv.findChildViewUnder(e.getX(), e.getY());
if (childView == null) {
return false;
}
selectView = childView;
selectPosition = rv.getChildAdapterPosition(childView);
/**
* 交给手势控制类来处理
*/
return mGestureDetector.onTouchEvent(e);
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
childView就是被点击的itemView,selectPosition就是被点击的position。
设置回调监听,将GestureDetector方法(手势操作方法)的处理结果回调回去,就能够在我们的activity中得到对应的点击事件。
1. 定义监听接口
设置builder是为了方便只重写点击事件,或者只重写长按事件。 又定义一个normal接口是为了区别于其他的点击事件,这里并没有定义其他的点击事件。如果扩展,定义内部接口会比较好。
public interface OnItemClickListener {
interface Normal {
void onItemClick(View view, int position);
void onItemLongClick(View view, int position);
class Builder implements Normal {
@Override
public void onItemClick(View view, int position) {
}
@Override
public void onItemLongClick(View view, int position) {
}
}
}
}
2. 添加监听构造方法
这是一个构造方法,将此方法作为一个实例,传入被调用的方法即可,调用方法见3.
public RecyclerItemClickListener(Context context, final OnItemClickListener.Normal mListener) {
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
/**
* 点击
*/
@Override
public boolean onSingleTapUp(MotionEvent e) {
if (selectView != null && mListener != null){
mListener.onItemClick(selectView, selectPosition);
return true;
}
return super.onSingleTapUp(e);
}
/**
* 长按
*/
@Override
public void onLongPress(MotionEvent e) {
if (selectView != null && mListener != null){
mListener.onItemLongClick(selectView, selectPosition);
}
}
});
}
3. 调用点击事件方法
// recyclerView 调用自己的addOnItemTouchListener方法,参数传入我们定义的类RecyclerItemClickListener的实例
recycleView.addOnItemTouchListener(new RecyclerItemClickListener(context, onItemClickListener));
// 这是回调方法,在下面的回调里面添加自己的处理逻辑,这里有三种写法
// 1.只回调单击事件
private RecyclerItemClickListener.OnItemClickListener.Normal onItemClickListener = new RecyclerItemClickListener.OnItemClickListener.Normal.Builder() {
@Override
public void onItemClick(View view, int position) {
// 在这里写自己的单击事件逻辑
}
};
// 2.只回调长按事件
private RecyclerItemClickListener.OnItemClickListener.Normal onItemClickListener = new RecyclerItemClickListener.OnItemClickListener.Normal.Builder() {
@Override
public void onItemLongClick(View view, int position) {
// 在这里写自己的长按事件逻辑
}
};
// 3.同时回调点击和长按事件
private RecyclerItemClickListener.OnItemClickListener.Normal onItemClickListener = new RecyclerItemClickListener.OnItemClickListener.Normal() {
@Override
public void onItemClick(View view, int position) {
// 在这里写自己的单击事件逻辑
}
@Override
public void onItemLongClick(View view, int position) {
// 在这里写自己的长按事件逻辑
}
};
好了,可点击,可长按,可复用的RecyclerView的点击事件就介绍到这里了,欢迎大家指正批评。
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
private GestureDetector mGestureDetector;
/**
* 被选择的view
*/
private View selectView;
/**
* 被选择view的position
*/
private int selectPosition;
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View childView = rv.findChildViewUnder(e.getX(), e.getY());
if (childView == null) {
return false;
}
selectView = childView;
selectPosition = rv.getChildAdapterPosition(childView);
/**
* 交给手势控制类来处理
*/
return mGestureDetector.onTouchEvent(e);
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
public RecyclerItemClickListener(Context context, final OnItemClickListener.Normal mListener) {
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
/**
* 点击
*/
@Override
public boolean onSingleTapUp(MotionEvent e) {
if (selectView != null && mListener != null){
mListener.onItemClick(selectView, selectPosition);
return true;
}
return super.onSingleTapUp(e);
}
/**
* 长按
*/
@Override
public void onLongPress(MotionEvent e) {
if (selectView != null && mListener != null){
mListener.onItemLongClick(selectView, selectPosition);
}
}
});
}
public interface OnItemClickListener {
interface Normal {
void onItemClick(View view, int position);
void onItemLongClick(View view, int position);
class Builder implements Normal {
@Override
public void onItemClick(View view, int position) {
}
@Override
public void onItemLongClick(View view, int position) {
}
}
}
}
}