關於在外部拿到RecyclerView的viewholder的幾種方式
在實際開發中,我們常常碰到這樣的需求,需要在外部拿到RecyclerView 中的viewHoler,從而動態的修改UI,在RecyclerView中,我們需要自己封裝點選事件,一般的做法是在recyclerview每一次bind的時候我們給viewholder的itemview註冊監聽事件,典型寫法如下:
@Override public void onBindViewHolder(final MyHolder holder, final int position) { Log.i("bind", list.size() + ""); holder.tv.setText(list.get(position)); if(listener != null) { holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { listener.onclick(holder,position,list.get(position)); } }); } }
因為點選事件的監聽寫在這個函式中,而這個函式的引數剛好又有ViewHolder,所以我們可以拿到點選的那一項的viewholder,從而動態的修改那一項的UI;那麼如果我們想要從adapter外部拿到其他項的viehodler。我們應該怎麼做呢
首先,我們來區分兩個函式。
getChildCount()這個函式在api中寫的很清楚,它的返回值是attached的child views的個數,那麼什麼時候view會被attach呢,答案很簡單,系統為了節約記憶體,只對可見的view進行attach,所以返回值其實就是可見的item的個數
getItemCount() 這個函式寫的也很明白,他的返回值是你給recyclerview繫結的item的個數,也就是總的個數,你傳進去的list的個數有幾個他就返回幾
如下做法是通過layoutManger拿到Viewholder的每一項,只要你ViewHolder中的控制元件不是私有的,就可以直接拿到他們,改變他們的屬性,但是這樣做迴圈的次數必須是manager.getChildCount(),因為這樣寫只能拿到RecyclerView可見的每一項的Viewholder,如果你的item數量比較多,不可見的item是拿不到的,如果你迴圈的次數是你傳入adapter的list的長度,那麼很有可能會報空指標異常,因為不可見的項是拿不到的。
RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
// manager.getItemCount();
// manager.getChildCount();
for (int i = 0; i < manager.getChildCount();i++){
View view = manager.getChildAt(i);
MyAdapter.MyHolder holder = (MyAdapter.MyHolder) recyclerView.getChildViewHolder(view);
}
有時候我們需要在初始化adapter時對不同的item進行不同的操作那麼我們應該怎麼做呢。我們知道當recyclerview繫結item的時候都會呼叫onbindViewHolder()方法,那麼我們只需要控制不同的item進行不同的操作就可以了,具體的方法類似於執行緒的中斷,你一定知道,如果需要中斷一個執行緒,最好的方法是通過標記位中斷,也就是說從外部改變執行緒中函式的執行條件,這樣執行緒就能自然而然的中斷,那麼在這裡,我們只需要維繫一個變數,從外部通過set方法來改變變數的值,從而能夠從外部修改item的屬性。
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder> {
private Context context;
private List<String> list;
private ItemClickListener listener;
private int which;
public void onBindViewHolder(final MyHolder holder, final int position) {
if(which == position){
//to do something
}
}
}
這樣我們就可以操作不同的item做不同的事情,當然這裡只是操作一個item做不同的事情,如果是多個item做不同的事情,那麼把變數換成list即可
在外部我們只需要
adapter.setWhich(int Which);
recyclerView.setAdapter(adapter); 就可以控制不同的item做不同的事情了