RecyclerView并没有像 ListView 提供一些关于 Item 的某种事件监听,唯一的就是 addOnItemTouchListener,原因可以看这个Google为什么不为Android中的RecyclerView添加Item的点击监听器?
所以我们需要自己来添加监听事件,网上大概有两种方法,以下来介绍这两种方法
第一种方法
先看完整代码在讲解。
public class OnClickAdapter extends RecyclerView.Adapter<OnClickAdapter.OnClickViewHolder> {
private ArrayList<String> list;//要显示的数据
private Context context;
private OnRecyclerViewItemClickListener onItemClickListener;//点击的接口
private OnRecyclerViewItemLongClickListener onItemLongClickListener;//长按的接口
/*
多参的构造方法
*/
public OnClickAdapter(ArrayList<String> list, Context context) {
this.list = list;
this.context = context;
}
@Override
public OnClickViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.main_item,parent,false);
OnClickViewHolder holder = new OnClickViewHolder(view);
return holder;
}
// Toast.makeText(context,"这是textView的点击事件",Toast.LENGTH_SHORT).show();
@Override
public void onBindViewHolder(OnClickViewHolder holder, final int position) {
holder.tvShow.setText(list.get(position));
holder.tvShow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onItemClickListener.OnItemClick(position);
}
});
//
holder.tvShow.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
onItemLongClickListener.OnItemLongClick(position);
return true;
}
});
}
@Override
public int getItemCount() {
return list.size();
}
public class OnClickViewHolder extends RecyclerView.ViewHolder {
TextView tvShow;
public OnClickViewHolder(View itemView) {
super(itemView);
tvShow = (TextView) itemView.findViewById(R.id.tv_show);
}
}
/*
暴露出去的点击事件的方法
*/
public void setOnItemClickListener(OnRecyclerViewItemClickListener onItemClickListener){
this.onItemClickListener = onItemClickListener;
}
/*
点击要实现的接口
*/
public interface OnRecyclerViewItemClickListener{
//接口中实现具体操作的抽象方法
public abstract void OnItemClick(int itemPosition);
}
/*
暴露出去的长按事件的方法
*/
public void setOnItemLongClickListener(OnRecyclerViewItemLongClickListener onItemLongClickListener){
this.onItemLongClickListener = onItemLongClickListener;
}
/*
长按要实现的接口
*/
public interface OnRecyclerViewItemLongClickListener{
//接口中实现具体操作的抽象方法
public abstract void OnItemLongClick(int itemPosition);
}
}
在Activity中调用
adapter.setOnItemClickListener(new OnClickAdapter.OnRecyclerViewItemClickListener() {
@Override
public void OnItemClick(int itemPosition) {
Toast.makeText(OnClickActivity.this,"点击"+list.get(itemPosition),Toast.LENGTH_SHORT).show();
}
});
adapter.setOnItemLongClickListener(new OnClickAdapter.OnRecyclerViewItemLongClickListener() {
@Override
public void OnItemLongClick(int itemPosition) {
Toast.makeText(OnClickActivity.this,"长按"+list.get(itemPosition),Toast.LENGTH_SHORT).show();
}
});
首先需要一个接口(相当于OnClickListener接口),里面是写一个你需要实现操作的方法(onClick方法),再写一个暴露的方法(相当于setOnClickListener方法),通过这个方法将接口传进来,最后通过在具体你需要点击的监听事件里面,通过这个接口来调用抽象方法。
如果实在很难理解,只要记住你写Button点击事件,需要什么就设计什么。
第二种方法
这种方法是通过那个唯一addOnItemTouchListener的方法,同上先是完整代码
public abstract class OnRecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
private GestureDetectorCompat mGestureDetector;//处理手势的类
private RecyclerView recyclerView;
public OnRecyclerItemClickListener(RecyclerView recyclerView){
this.recyclerView = recyclerView;
mGestureDetector = new GestureDetectorCompat(recyclerView.getContext(),new ItemTouchHelperGestureListener());
}
//暴露的点击方法
public abstract void onItemClick(RecyclerView.ViewHolder vh);
//暴露的长按方法
public abstract void onItemLongClick(RecyclerView.ViewHolder vh);
//事件拦截
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
mGestureDetector.onTouchEvent(e);
return false;
}
//事件处理
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
mGestureDetector.onTouchEvent(e);
}
//处理触摸事件冲突
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
//处理手势的类
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 vh = recyclerView.getChildViewHolder(child);
onItemClick(vh);
}
return true;
}
//长按事件
@Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null) {
RecyclerView.ViewHolder vh = recyclerView.getChildViewHolder(child);
onItemLongClick(vh);
}
}
}
}
在Activity中调用
myRecyclerView.addOnItemTouchListener(new OnRecyclerItemClickListener(myRecyclerView) {
@Override
public void onItemClick(RecyclerView.ViewHolder vh) {
Toast.makeText(OnClickActivity.this,"点击"+list.get(vh.getLayoutPosition()),Toast.LENGTH_SHORT).show();
}
@Override
public void onItemLongClick(RecyclerView.ViewHolder vh) {
Toast.makeText(OnClickActivity.this,"长按"+list.get(vh.getLayoutPosition()),Toast.LENGTH_SHORT).show();
}
});
首先addOnItemTouchListener是一个添加触摸监听的方法,这样就可以手势来监听一个点击手势,然后就需要新建一个GestureDetector.SimpleOnGestureListener来帮助判断点击还是长按,最后还需要来判断你到底点击是哪一个Item,所以使用findChildViewUnder方法可以通过点击的坐标来判断item,再使用另一个方法getChildViewHolder方法,可以获得该item的ViewHolder,将其传给暴露方法。
感谢这位作者,详细的查看RecyclerView无法添加onItemClickListener最佳的高效解决方案
但是有一个缺点,它不太好处理itemView里面的监听事件,会有所冲突。
RecyclerView的系列的文章
- 第一篇RecyclerView的基本使用 RecyclerView使用(一)
- 第二篇有关多种Item,添加,删除 RecyclerView使用(二)
- 第三篇RecyclerView的监听方法RecyclerView使用(三)
- 第四篇RecyclerView的拖动和滑动删除RecyclerView使用(四)