RecyclerView通用适配器的实现

nde7 8年前

分析

  • 我们需要在RecyclerViewAdapter内部维持一个数据集合的引用
  • 需要实现Item的点击事件,包括短按和长按,并需要向外部提供设置监听器的方法
  • 这个适配器必须通用,所以应该是泛型的,并且ViewHolder也是通用的,可以采用SparseArray维持View的所有集合
  • 在RecyclerViewAdapter内部需要实现数据的绑定(抽象方法,延迟到子类实现),监听器的绑定

编写监听器

分为短按事件和长按事件

  • 短按监听器
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);  }

  • 长按监听器
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);  }

编写通用适配器

  • 设置监听器
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;      }      }

  • 编写构造方法,将数据集合进行赋值
    /**       * data       */      protected List<T> mList;        /**       * @param list the datas to attach the adapter       */      public BaseRecyclerViewAdapter(List<T> list) {          mList = list;      }

实现几个必要的方法,比如获得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();  }

  • 实现将布局文件映射成View的方法
  /**       * 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);      }

实现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;                  }              });          }      }

  • 实现通用ViewHolder,内部使用SparseArray维持View对象
    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;          }      }

内部实现了一个泛型的getView方法,其作用就是将View缓存至SparseArray中去

  • 实现通用ViewHolder的一些属性设置方法,采用链式调用,返回this对象
      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;          }

源码

来自:http://blog.csdn.net/sbsujjbcy/article/details/46480885