在上一篇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+"元素");
}
});
點擊和長按的結果如下
這樣是不是方便很多了呢?有更好的方法望大神不吝賜教!很晚了,就到這裏吧。