设置监听方法一
- Adapter 中定义一个 Interface;
- Adapter 中的保留一个接口对象;
- 通过 adapter 的 set 、 get 方法设置接口对象;
- 在 onBindViewHolder 方法中设置 itemView、view clickListener ,并在接口对象不为 null 时回调给 activity、fragment;
public class DemoRecyclerViewAdapter extends RecyclerView.Adapter {
private ArrayList<String> data;
/**
* adapter 中item点击事件的监听对象.
*/
private OnClickListener onClickListener;
public OnClickListener getOnClickListener() {
return onClickListener;
}
public void setOnClickListener(OnClickListener onClickListener) {
this.onClickListener = onClickListener;
}
/**
* 获得 item 布局.
*/
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = View.inflate(parent.getContext(), R.layout.demo_item_layout, null);
return itemView;
}
/**
* 绑定数据.
*/
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
final View itemView = holder.itemView;
TextView demoTextView = (TextView) itemView.findViewById(R.id.demo_text_view);
demoTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 设置单击事件并回调给页面
if (onClickListener != null) {
onClickListener.onClick(itemView, holder.getLayoutPosition());
}
}
});
demoTextView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
// 设置长点击事件并回调给页面
if (onClickListener != null) {
onClickListener.onLongClick(itemView, holder.getLayoutPosition());
return true;
}
return false;
}
});
}
/**
* 返回列表长度.
*/
@Override
public int getItemCount() {
return data == null ? 0 : data.size();
}
/**
* 定义点击事件回调接口.
*/
interface OnClickListener {
/**
* 点击事件.
*/
void onClick(View itemView, int position);
/**
* 长点击事件.
*/
void onLongClick(View itemView, int position);
}
}
使用方法
在 Activity、Fragment 中直接通过 adapter 设置监听即可
DemoRecyclerViewAdapter adapter = new DemoRecyclerViewAdapter();
adapter.setOnClickListener(new DemoRecyclerViewAdapter.OnClickListener() {
@Override
public void onClick(View itemView, int position) {
// click...
}
@Override
public void onLongClick(View itemView, int position) {
// longClick...
}
});
设置监听方法二
RecyclerView 虽然没有提供如ListView的 setOnClickListener() 方法,但是,提供了一个现成的 itemTouch 事件,内部接口: OnItemTouchListener
public static interface OnItemTouchListener {
// 是否拦截触摸事件
// true 拦截
// false 不拦截
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e);
// 触摸事件
public void onTouchEvent(RecyclerView rv, MotionEvent e);
// childView 是否允许拦截事件
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept);
}
从方法中可以看到,其处理的是 item 的 Touch 事件的分发;而我们只是需要处理第一个方法 是否拦截触摸事件;
官方给了一个默认实现类,一般情况下集成该类处理,对于不需要处理的方法不用重写即可,减少代码量,更美观一些;
public static class SimpleOnItemTouchListener implements RecyclerView.OnItemTouchListener {
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
- 官方提供了一个手势检测类 GestureDetectorCompat,其很好的封装了各种手势的操作,并暴露有限的方法,便于进行开发;
- RecyclerView 提供了根据坐标获取 ChildView 的方法;
- 获得 ChildView ,可以通过 getChildViewHolder(child) 方法获得该 child 的 ViewHolder;
具体看下面的Demo:
public class OnRecyclerViewItemClickListener extends RecyclerView.SimpleOnItemTouchListener {
private GestureDetectorCompat gestureDetectorCompat;
private RecyclerView recyclerView;
protected OnRecyclerViewItemClickListener(RecyclerView recyclerView) {
this.recyclerView = recyclerView;
gestureDetectorCompat = new GestureDetectorCompat(recyclerView.getContext(), new ItemTouchHelperGestureListener());
}
protected void onItemClick(@NonNull RecyclerView.ViewHolder viewHolder) {
}
protected void onItemLongClick(@NonNull RecyclerView.ViewHolder viewHolder) {
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
gestureDetectorCompat.onTouchEvent(e);
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
gestureDetectorCompat.onTouchEvent(e);
}
private class ItemTouchHelperGestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onSingleTapUp(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null) {
RecyclerView.ViewHolder childViewHolder = recyclerView.getChildViewHolder(child);
// 单击反馈处理
onItemClick(childViewHolder);
}
// 拦截事件 Intercept events;
// return super.onSingleTapUp(e);
return true;
}
@Override
public void onLongPress(MotionEvent e) {
super.onLongPress(e);
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null) {
RecyclerView.ViewHolder childViewHolder = recyclerView.getChildViewHolder(child);
// 长按反馈处理
onItemLongClick(childViewHolder);
}
}
}
}
使用方法
recyclerView.addOnItemTouchListener(new OnRecyclerViewItemClickListener(recyclerView) {
@Override
protected void onItemClick(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
super.onItemClick(viewHolder, position);
}
}
@Override
protected void onItemLongClick(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
super.onItemLongClick(viewHolder, position);
}
});