在上一篇RecyclerView新体验(1)介绍了RecyclerView的简单使用方法和分割线的设置,但是我们仔细一看,RecyclerView并没有给我们提供点击事件,尼~玛,这绝对是个坑啊,没办法,既然进了坑就想办法跳出去呗。
下面我们像ListView一样,写出点击和长按两个方法。Adapter代码如下:
public class CommonClickRecyclerViewAdapter extends RecyclerView.Adapter<CommonClickRecyclerViewAdapter.MyViewHolder> {
private Context context;
private List<String> list;
//定义接口
public interface OnItemClickListener {
void onItemClick(View view, int position);
} //定义接口
public interface OnItemLongClickListener {
void onItemLongClick(View view, int position);
}
//声明接口变量
private OnItemClickListener listener;
//声明接口变量
private OnItemLongClickListener lListener;
//暴露给使用者调用
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}
public void setOnItemLongClickListener(OnItemLongClickListener lListener) {
this.lListener = lListener;
}
private ListView lv;
public CommonClickRecyclerViewAdapter(Context context, List<String> list) {
this.context = context;
this.list = list;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item_rcv, null));
}
@Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
holder.tv.setText(list.get(position));
if (listener != null) {
holder.layout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.onItemClick(view, position);
}
});
}
if (lListener != null) {
holder.layout.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
lListener.onItemLongClick(view, position);
return false;
}
});
}
}
@Override
public int getItemCount() {
return list.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView tv;
RelativeLayout layout;
public MyViewHolder(View itemView) {
super(itemView);
tv = (TextView) itemView.findViewById(R.id.tv);
layout = (RelativeLayout) itemView.findViewById(R.id.rl_item);
}
}
}
这时候只需要我们在对RecyclerView的adapter进行监听就好,值得注意的是回调的参数是view和当前item的position(位置),要得到相应的值可通过position进行获取。监听代码如下:
adapter2.setOnItemClickListener(new CommonClickRecyclerViewAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Log.e("一样一样","点击了"+position+"元素");
}
});
adapter2.setOnItemLongClickListener(new CommonClickRecyclerViewAdapter.OnItemLongClickListener() {
@Override
public void onItemLongClick(View view, int position) {
Log.e("一样一样","点击了"+position+"元素");
}
});
得到的效果如下图:
到此,简单的点击和长按事件完成了,但是感觉有点不爽,每个Adapter都要自己写点击事件,那不是很麻烦?
我们想着点击事件回调的是position,那也就是与实体没有关系,于是我想到了在getview中把点击外的抽出来一个方法,做成一个基类。注:这次写的是一个接口回调两个方法。
public abstract class RAdapter<T extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
//定义接口
public interface OnItemClickListener {
void onItemClick(View view, int position);
void onItemLongClick(View view, int position);
}
//声明接口变量
private OnItemClickListener listener;
//暴露给使用者调用
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, final int position) {
onBindView(viewHolder, position);
if(listener != null) {
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.onItemClick(view,position);
}
});
viewHolder.itemView.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
listener.onItemLongClick(view,position);
//如果是长按事件,那么久不用再触发点击事件了,所以返回true
//将事件直接消费掉??
return true;
}
});
}
}
public abstract void onBindView(RecyclerView.ViewHolder holder, int position);
}
这时候我们写的Adapter只要继承了RAdapter就可以在Activity中对adapter进行监听了,没有必要每次都在adapte中重写点击事件。
自己写的Adapter如下:
public class BaseOnClickAdapter extends RAdapter<BaseOnClickAdapter.MyViewHolder> {
private Context context;
private List<String> list;
public BaseOnClickAdapter(Context context, List<String> list) {
this.context = context;
this.list = list;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item_rcv,null));
}
@Override
public int getItemCount() {
return list.size();
}
@Override
public void onBindView(RecyclerView.ViewHolder holder, int position) {
if(holder instanceof MyViewHolder) {
((MyViewHolder) holder).tv.setText(list.get(position));
}
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView tv;
public MyViewHolder(View itemView) {
super(itemView);
tv = (TextView) itemView.findViewById(R.id.tv);
}
}
}
这时候不是重写onBindViewHolder,而是重写onBindView()方法就好。监听方法:
adapter2.setOnItemClickListener(new RAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Log.e("一样一样","点击了"+position+"元素");
}
@Override
public void onItemLongClick(View view, int position) {
Log.e("一样一样","长按了"+position+"元素");
}
});
点击和长按的结果如下
这样是不是方便很多了呢?有更好的方法望大神不吝赐教!很晚了,就到这里吧。