1. 程式人生 > >關於在外部拿到RecyclerView的viewholder的幾種方式

關於在外部拿到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做不同的事情了