RecyclerView通用適配器的實現

nde7 9年前發布 | 11K 次閱讀 Android開發 移動開發 RecyclerView

分析

  • 我們需要在RecyclerViewAdapter內部維持一個數據集合的引用
  • 需要實現Item的點擊事件,包括短按和長按,并需要向外部提供設置監聽器的方法
  • 這個適配器必須通用,所以應該是泛型的,并且ViewHolder也是通用的,可以采用SparseArray維持View的所有集合
  • 在RecyclerViewAdapter內部需要實現數據的綁定(抽象方法,延遲到子類實現),監聽器的綁定
  • </ul>

    編寫監聽器

    分為短按事件和長按事件

    • 短按監聽器
    • </ul>

      package cn.edu.zafu.base.adapter.listener;

      import android.view.View;

      /**

      • Created by lizhangqu on 2015/6/3. */ public interface OnItemClickListener<T> { void onClick(View view, T item); }</pre>
        • 長按監聽器
        package cn.edu.zafu.base.adapter.listener;

      import android.view.View;

      /**

      • Created by lizhangqu on 2015/6/3. */ public interface OnItemLongClickListener<T> { void onLongClick(View view, T item); }</pre>

        編寫通用適配器

        • 設置監聽器
        package cn.edu.zafu.base.adapter;

      import android.support.v7.widget.RecyclerView; import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView;

      import java.util.List;

      import cn.edu.zafu.base.adapter.listener.OnItemClickListener; import cn.edu.zafu.base.adapter.listener.OnItemLongClickListener;

      /**

      • this is a BaseAdapter for RecyclerView
      • author lizhangqu
      • version 1.0
      • date 2015/6/3. */ public abstract class BaseRecyclerViewAdapter<T, VH extends BaseRecyclerViewAdapter.SparseArrayViewHolder> extends RecyclerView.Adapter<VH> {

        /**

        • click listener */ protected OnItemClickListener mOnItemClickListener; /**
        • long click listener */ protected OnItemLongClickListener mOnItemLongClickListener;

          /**

        • set a long click listener *
        • @param onItemLongClickListener */ public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener) { mOnItemLongClickListener = onItemLongClickListener; }

          /**

        • set a click listener *
        • @param onItemClickListener */ public void setOnItemClickListener(OnItemClickListener onItemClickListener) { mOnItemClickListener = onItemClickListener; }

      }</pre>

      • 編寫構造方法,將數據集合進行賦值
      • </ul>

            /**

         * data
         */
        protected List<T> mList;
        
        /**
         * @param list the datas to attach the adapter
         */
        public BaseRecyclerViewAdapter(List<T> list) {
            mList = list;
        }</pre><br />
        

        實現幾個必要的方法,比如獲得Item以及覆寫getItemCount方法

        /**

        • get a item by index *
        • @param position
        • @return */ protected T getItem(int position) { return mList.get(position); }

        @Override public int getItemCount() { return mList.size(); }</pre>

        • 實現將布局文件映射成View的方法
        • </ul>

            /**

           * inflate a view by viewgroup ,id ,etc
           *
           * @param viewGroup
           * @param layoutId
           * @return
           */
          protected View inflateItemView(ViewGroup viewGroup, int layoutId) {
              return inflateItemView(viewGroup, layoutId, false);
          }
          
          /**
           * inflate a view by viewgroup ,id ,etc
           *
           * @param viewGroup
           * @param layoutId
           * @param attach
           * @return
           */
          protected View inflateItemView(ViewGroup viewGroup, int layoutId, boolean attach) {
              return LayoutInflater.from(viewGroup.getContext()).inflate(layoutId, viewGroup, attach);
          }</pre><br />
          

          實現onBindViewHolder方法,這一步很重要,將具體實現抽取到兩個方法中去實現,bindDataToItemView是一個抽象方法,延遲到子類實現,bindItemViewClickListener方法設置監聽器

           /**

           * a final function to avoid you override
           * use template design pattern
           *
           * @param vh
           * @param position
           */
          @Override
          public final void onBindViewHolder(VH vh, int position) {
              final T item = getItem(position);
              bindDataToItemView(vh, item);
              bindItemViewClickListener(vh, item);
          }
          
          /**
           * bind data to itemview
           *
           * @param vh   viewholder
           * @param item item
           */
          protected abstract void bindDataToItemView(VH vh, T item);
          /**
           * bind click listner to itemview
           *
           * @param vh   viewholder
           * @param item item
           */
          protected final void bindItemViewClickListener(VH vh, final T item) {
              if (mOnItemClickListener != null) {
                  vh.itemView.setOnClickListener(new View.OnClickListener() {
                      @Override
                      public void onClick(View view) {
                          mOnItemClickListener.onClick(view, item);
                      }
                  });
              }
              if (mOnItemLongClickListener != null) {
                  vh.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                      @Override
                      public boolean onLongClick(View v) {
                          mOnItemLongClickListener.onLongClick(v, item);
                          return true;
                      }
                  });
              }
          }</pre><br />
          

          • 實現通用ViewHolder,內部使用SparseArray維持View對象
          • </ul>

                public static class SparseArrayViewHolder extends RecyclerView.ViewHolder {
                    private final SparseArray<View> views;

                public SparseArrayViewHolder(View itemView) {
                    super(itemView);
                    views = new SparseArray<View>();
                }
            
                public <T extends View> T getView(int id) {
                    View view = views.get(id);
                    if (view == null) {
                        view = itemView.findViewById(id);
                        views.put(id, view);
                    }
                    return (T) view;
                }
            }</pre><br />
            

            內部實現了一個泛型的getView方法,其作用就是將View緩存至SparseArray中去

            • 實現通用ViewHolder的一些屬性設置方法,采用鏈式調用,返回this對象
            • </ul>

                    public SparseArrayViewHolder setText(int viewId, String value) {
                          TextView view = getView(viewId);
                          view.setText(value);
                          return SparseArrayViewHolder.this;
                      }

                  public SparseArrayViewHolder setTextColor(int viewId, int textColor) {
                      TextView view = getView(viewId);
                      view.setTextColor(textColor);
                      return SparseArrayViewHolder.this;
                  }
              
                  public SparseArrayViewHolder setImageResource(int viewId, int imageResId) {
                      ImageView view = getView(viewId);
                      view.setImageResource(imageResId);
                      return SparseArrayViewHolder.this;
                  }
              
                  public SparseArrayViewHolder setBackgroundColor(int viewId, int color) {
                      View view = getView(viewId);
                      view.setBackgroundColor(color);
                      return SparseArrayViewHolder.this;
                  }
              
                  public SparseArrayViewHolder setBackgroundResource(int viewId, int backgroundRes) {
                      View view = getView(viewId);
                      view.setBackgroundResource(backgroundRes);
                      return SparseArrayViewHolder.this;
                  }
              
                  public SparseArrayViewHolder setVisible(int viewId, boolean visible) {
                      View view = getView(viewId);
                      view.setVisibility(visible ? View.VISIBLE : View.GONE);
                      return SparseArrayViewHolder.this;
                  }
              
                  public SparseArrayViewHolder setOnClickListener(int viewId, View.OnClickListener listener) {
                      View view = getView(viewId);
                      view.setOnClickListener(listener);
                      return SparseArrayViewHolder.this;
                  }
              
                  public SparseArrayViewHolder setOnTouchListener(int viewId, View.OnTouchListener listener) {
                      View view = getView(viewId);
                      view.setOnTouchListener(listener);
                      return SparseArrayViewHolder.this;
                  }
              
                  public SparseArrayViewHolder setOnLongClickListener(int viewId, View.OnLongClickListener listener) {
                      View view = getView(viewId);
                      view.setOnLongClickListener(listener);
                      return SparseArrayViewHolder.this;
                  }
              
                  public SparseArrayViewHolder setTag(int viewId, Object tag) {
                      View view = getView(viewId);
                      view.setTag(tag);
                      return SparseArrayViewHolder.this;
                  }</pre><br />
              

              源碼

 本文由用戶 nde7 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!