RecyclerView并没有像ListView那样提供了OnItemClick,OnItemLongClick等事件回调接口,所以,我们需要自己去实现。
为了后面的几种方式都可以用同一的回调接口来实现Click和LongClick事件,我们先定义一个回调事件接口。
public static interface OnItemClickListener {
void onItemClick(View view);
void onItemLongClick(View view);
}
1 . 通过Adapter来处理
在Adapter的onCreateViewHolder和onBindViewHolder函数添加如下代码
@Override
public ListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ListViewHolder viewHolder = new ListViewHolder(
mInflater.inflate(R.layout.list_item, parent, false));
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mItemClickListener.onItemClick(V);
}
});
viewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
mItemClickListener.onItemLongClick(v);
return true;
}
});
return viewHolder;
}
@Override
public void onBindViewHolder(ListViewHolder holder, final int position) {
if (mData != null) {
holder.mIndex.setText(Integer.toString(position));
holder.mTitle.setText(mData.get(position).getTitle());
holder.itemView.setTag(mData.get(position).getId());
}
}
其中,mItemClickListener为注册进来的Click回调监听,一般为对应的Activity或Fragment。在onBindViewHolder中,我们对ItemView设置了Tag属性,将数据的ID设置进去,在Activity或Fragment中可以通过获取view的Tag来获取当前点击item的Id值。另外,在中,可以直接通过RecyclerView.getChildAdapterPosition获取到当前点击的Item的列表索引。
mListAdapter.setOnViewItemClickListener(new ListAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view) {
int position = mRecyclerView.getChildAdapterPosition(view);
Toast.makeText(this, "onItemClick : " + position, Toast.LENGTH_SHORT).show();
}
@Override
public void onItemLongClick(View view) {
int position = mRecyclerView.getChildAdapterPosition(view);
Toast.makeText(this, "onItemLongClick : " + position, Toast.LENGTH_SHORT).show();
}
}
2 . 通过OnItemTouchListener来监听touch事件并转化为点击事件
创建类RecyclerViewItemTouchListener继承RecyclerView.SimpleOnItemTouchListener
public class RecyclerViewItemTouchListener extends RecyclerView.SimpleOnItemTouchListener {
private OnItemClickListener mClickListener;
private GestureDetectorCompat mGestureDetector;
public RecyclerViewItemTouchListener(final RecyclerView recyclerView,
OnItemClickListener listener) {
this.mClickListener = listener;
mGestureDetector = new GestureDetectorCompat(recyclerView.getContext(),
new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
View childView = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mClickListener != null) {
mClickListener.onItemClick(childView);
}
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View childView = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mClickListener != null) {
mClickListener.onItemLongClick(childView);
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
mGestureDetector.onTouchEvent(e);
return false;
}
}
在Activity或Fragment中添加OnItemTouchListener。
mRecyclerView.addOnItemTouchListener(new RecyclerViewItemTouchListener(mRecyclerView, new RecyclerViewItemTouchListener.OnItemClickListener() {
@Override
public void onItemClick(View view) {
}
@Override
public void onItemLongClick(View view, int position) {
}
});
3 . 通过OnChildAttachStateChangeListener在Item在Attach时添加点击事件
创建RecyclerViewClickSupport类,继承RecyclerView.OnChildAttachStateChangeListener
public class RecyclerViewClickSupport implements RecyclerView.OnChildAttachStateChangeListener {
private View.OnClickListener mItemClickListener = null;
private View.OnLongClickListener mItemLongClickListener = null;
private RecyclerView mRecyclerView = null;
public RecyclerViewClickSupport(RecyclerView view, View.OnClickListener listener,
View.OnLongClickListener listener2){
mRecyclerView = view;
mItemClickListener = listener;
mItemLongClickListener = listener2;
view.addOnChildAttachStateChangeListener(this);
}
@Override
public void onChildViewAttachedToWindow(View view) {
if (mItemClickListener != null){
view.setOnClickListener(mItemClickListener);
}
if (mItemLongClickListener != null){
view.setOnLongClickListener(mItemLongClickListener);
}
}
@Override
public void onChildViewDetachedFromWindow(View view) {
}
}
在Activity或Fragment中添加RecyclerViewClickSupport实现对RecyclerView的Item的点击事件的监听。
mRCClickSupport = new RecyclerViewClickSupport(mRecyclerView, new View.OnClickListener() {
@Override
public void onClick(View v) {
}
}, new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
return false;
}
});
以上的三种实现方式中,其中:
- 方式二没有办法对item的子view进行事件监听,而且因为没有为item真正的添加Click事件监听,所以Item的Click按下效果出不来。
- 方法一和方法三,更建议使用方法一,毕竟Adapter对Item的数据以及布局都有处理。
- 方法三可以封装为独立的类,但如果要处理子view,难免还要加入布局相关的代码,这样就进一个降低了代码的耦合。