RecyclerView不再負責Item視圖的布局及顯示,是以RecyclerView也沒有為Item開放OnItemClick等點選事件,這就需要開發者自己實作。部落格最下面有Demo程式運作動畫。
因為ViewHolder我們可以拿到每個Item的根布局,是以如果我們為根布局設定單獨的OnClick監聽并将其開放給Adapter,那不就可以在組裝RecyclerView時就能夠設定ItemClickListener,隻不過這個Listener不是設定到RecyclerView上而是設定到Adapter。
給一個測試接口:
String path="http://japi.juhe.cn/joke/content/list.from?key= 874ed931559ba07aade103eee279bb37 &page=2&pagesize=10&sort=asc&time=1418745237";
最終目的
模拟ListView的setOnItemClickListener()方法,調用者隻須調用類似于setOnItemClickListener的東西就能獲得被點選item的相關資料。
原理
為RecyclerView的每個子item設定setOnClickListener,然後在onClick中再調用一次對外封裝的接口,将這個事件傳遞給外面的調用者。而“為RecyclerView的每個子item設定setOnClickListener”在Adapter中設定。其實直接在onClick中也能完全處理item的點選事件,但是這樣會破壞代碼的邏輯。
步驟
adapter中
1.在MyAdapter中定義如下接口,模拟ListView的OnItemClickListener:
//定義一個接口
public interface OnRecyclerViewItemClickListener {
void onItemClick(View view , String data);
}
聲明一個這個接口的變量
private OnRecyclerViewItemClickListener mOnItemClickListener = null;
在onCreateViewHolder()中為每個item添加點選事件
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = View.inflate(context, R.layout.recyclerviewitem, null);
MyViewHolder myViewHolder = new MyViewHolder(view);
//将建立的View注冊點選事件
view.setOnClickListener(this);
return myViewHolder;
}
将點選事件轉移給外面的調用者:
@Override
public void onClick(View view) {
if (mOnItemClickListener != null) {
//注意這裡使用getTag方法擷取資料
mOnItemClickListener.onItemClick(view,view.getTag().toString());
}
}
注意上面調用接口的onItemClick()中的v.getTag()方法,這需要在onBindViewHolder()方法中設定和item相關的資料
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
viewHolder.mTextView.setText(datas[position]);
//将資料儲存在itemView的Tag中,以便點選時進行擷取
viewHolder.itemView.setTag(datas[position]);
}
最後暴露給外面的調用者,定義一個設定Listener的方法():
public void setOnItemClickListener(OnRecyclerViewItemClickListener listener) {
this.mOnItemClickListener = listener;
}
以上所有步驟都發生在自定義的adapter中,典型的觀察者模式,有點繞的地方在于,這裡涉及到兩個觀察者模式的使用,view的setOnClickListener本來就是觀察者模式,我們将這個觀察者模式的事件監聽傳遞給了我們自己的觀察者模式。
在Activity中使用
MyRecyclerAdapter adapter=new MyRecyclerAdapter(RecycleActivity.this,data);
recycleview.setAdapter(adapter);
adapter.setOnItemClickListener(new MyRecyclerAdapter.OnRecyclerViewItemClickListener() {
@Override
public void onItemClick(View view, String data) {
//DO your fucking bussiness here!】
Toast.makeText(RecycleActivity.this,data,Toast.LENGTH_SHORT).show();
}
});