content: 
  package com.xiaochao.lcrapiddeveloplibrary;
  
  import android.animation.Animator;
  import android.content.Context;
  import android.support.annotation.IntDef;
  import android.support.v7.widget.RecyclerView;
  import android.support.v7.widget.StaggeredGridLayoutManager;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.view.ViewGroup;
  import android.view.animation.Interpolator;
  import android.view.animation.LinearInterpolator;
  
  import com.xiaochao.lcrapiddeveloplibrary.animation.AlphaInAnimation;
  import com.xiaochao.lcrapiddeveloplibrary.animation.BaseAnimation;
  import com.xiaochao.lcrapiddeveloplibrary.animation.CustomAnimation;
  import com.xiaochao.lcrapiddeveloplibrary.animation.ScaleInAnimation;
  import com.xiaochao.lcrapiddeveloplibrary.animation.SlideInBottomAnimation;
  import com.xiaochao.lcrapiddeveloplibrary.animation.SlideInLeftAnimation;
  import com.xiaochao.lcrapiddeveloplibrary.animation.SlideInRightAnimation;
  
  import java.lang.annotation.Retention;
  import java.lang.annotation.RetentionPolicy;
  import java.util.ArrayList;
  import java.util.List;
  
  
  public abstract class BaseQuickAdapter<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
  
      private boolean mNextLoadEnable = false;
      private boolean mLoadingMoreEnable = false;
      private boolean mFirstOnlyEnable = true;
      private boolean mOpenAnimationEnable = false;
      private boolean mEmptyEnable;
      private boolean mHeadAndEmptyEnable;
      private boolean mFootAndEmptyEnable;
      private Interpolator mInterpolator = new LinearInterpolator();
      private int mDuration = 300;
      private int mLastPosition = -1;
      private OnRecyclerViewItemClickListener onRecyclerViewItemClickListener;
      private OnRecyclerViewItemLongClickListener onRecyclerViewItemLongClickListener;
      private RequestLoadMoreListener mRequestLoadMoreListener;
      @AnimationType
      private BaseAnimation mCustomAnimation;
      private BaseAnimation mSelectAnimation = new AlphaInAnimation();
      private View mHeaderView;
      private View mFooterView;
      private int pageSize = -1;
      private View mContentView;
      /**
       * View to show if there are no items to show.
       */
      private View mEmptyView;
  
      protected static final String TAG = BaseQuickAdapter.class.getSimpleName();
      protected Context mContext;
      protected int mLayoutResId;
      protected LayoutInflater mLayoutInflater;
      protected List<T> mData;
      protected static final int HEADER_VIEW = 0x00000111;
      protected static final int LOADING_VIEW = 0x00000222;
      protected static final int FOOTER_VIEW = 0x00000333;
      protected static final int EMPTY_VIEW = 0x00000555;
      protected static final int UPDAYE_VIEW = 0x00000666;
      private View mLoadingView;
  
      @IntDef({ALPHAIN, SCALEIN, SLIDEIN_BOTTOM, SLIDEIN_LEFT, SLIDEIN_RIGHT,SLIDEIN_CUSTOM})
      @Retention(RetentionPolicy.SOURCE)
      public @interface AnimationType {
      }
  
      /**
       * Use with {@link #openLoadAnimation}
       */
      public static final int ALPHAIN = 0x00000001;
      /**
       * Use with {@link #openLoadAnimation}
       */
      public static final int SCALEIN = 0x00000002;
      /**
       * Use with {@link #openLoadAnimation}
       */
      public static final int SLIDEIN_BOTTOM = 0x00000003;
      /**
       * Use with {@link #openLoadAnimation}
       */
      public static final int SLIDEIN_LEFT = 0x00000004;
      /**
       * Use with {@link #openLoadAnimation}
       */
      public static final int SLIDEIN_RIGHT = 0x00000005;
  
      public static final int SLIDEIN_CUSTOM=0x00000006;
  
  
      /**
       * call the method will not enable the loadMore funcation and the params pageSize is invalid
       * more infomation see{@link  public void openLoadMore(int pageSize, boolean enable),@link  public void setOnLoadMoreListener(RequestLoadMoreListener requestLoadMoreListener)} method
       *
       * @param pageSize
       * @param requestLoadMoreListener
       */
      @Deprecated
      public void setOnLoadMoreListener(int pageSize, RequestLoadMoreListener requestLoadMoreListener) {
          setOnLoadMoreListener(requestLoadMoreListener);
      }
  
      public void setOnLoadMoreListener(RequestLoadMoreListener requestLoadMoreListener) {
          this.mRequestLoadMoreListener = requestLoadMoreListener;
      }
  
      public void setDuration(int duration) {
          mDuration = duration;
      }
  
      /**
       * when adapter's data size than pageSize and enable is true,the loading more function is enable,or disable
       *
       * @param pageSize
       * @param enable
       */
      public void openLoadMore(int pageSize, boolean enable) {
          this.pageSize = pageSize;
          mNextLoadEnable = enable;
  
      }
  
      /**
       * call the method before you should call setPageSize() method to setting up the enablePagerSize value,whether it will  invalid
       * enable the loading more data function if enable's value is true,or disable
       *
       * @param enable
       */
      public void openLoadMore(boolean enable) {
          mNextLoadEnable = enable;
  
      }
  
      /**
       * setting up the size to decide the loading more data funcation whether enable
       * enable if the data size than pageSize,or diable
       *
       * @param pageSize
       */
      public void setPageSize(int pageSize) {
          this.pageSize = pageSize;
      }
  
      /**
       * return the value of pageSize
       *
       * @return
       */
      public int getPageSize() {
          return this.pageSize;
      }
  
      public void setOnRecyclerViewItemClickListener(OnRecyclerViewItemClickListener onRecyclerViewItemClickListener) {
          this.onRecyclerViewItemClickListener = onRecyclerViewItemClickListener;
      }
  
      public interface OnRecyclerViewItemClickListener {
          public void onItemClick(View view, int position);
      }
  
      public void setOnRecyclerViewItemLongClickListener(OnRecyclerViewItemLongClickListener onRecyclerViewItemLongClickListener) {
          this.onRecyclerViewItemLongClickListener = onRecyclerViewItemLongClickListener;
      }
  
      public interface OnRecyclerViewItemLongClickListener {
          public boolean onItemLongClick(View view, int position);
      }
  
      private OnRecyclerViewItemChildClickListener mChildClickListener;
  
      public void setOnRecyclerViewItemChildClickListener(OnRecyclerViewItemChildClickListener childClickListener) {
          this.mChildClickListener = childClickListener;
      }
  
      public interface OnRecyclerViewItemChildClickListener {
          void onItemChildClick(BaseQuickAdapter adapter, View view, int position);
      }
  
      public class OnItemChildClickListener implements View.OnClickListener {
          public int position;
  
          @Override
          public void onClick(View v) {
              if (mChildClickListener != null)
                  mChildClickListener.onItemChildClick(BaseQuickAdapter.this, v, position - getHeaderViewsCount());
          }
      }
  
  
      /**
       * Same as QuickAdapter#QuickAdapter(Context,int) but with
       * some initialization data.
       *
       * @param layoutResId The layout resource id of each item.
       * @param data        A new list is created out of this one to avoid mutable list
       */
      public BaseQuickAdapter( int layoutResId, List<T> data) {
          this.mData = data == null ? new ArrayList<T>() : data;
          if (layoutResId != 0) {
              this.mLayoutResId = layoutResId;
          }
      }
  
      public BaseQuickAdapter( List<T> data) {
          this(0, data);
      }
  
      public BaseQuickAdapter(View contentView, List<T> data) {
          this( 0, data);
          mContentView = contentView;
      }
  
  
      public void remove(int position) {
          mData.remove(position);
          notifyItemRemoved(position + getHeaderViewsCount());
  
      }
  
      public void add(int position, T item) {
          mData.add(position, item);
          notifyItemInserted(position);
      }
  
  
      /**
       * setting up a new instance to data;
       *
       * @param data
       */
      public void setNewData(List<T> data) {
          this.mData = data;
          if (mRequestLoadMoreListener != null) {
              mNextLoadEnable = true;
              mFooterView = null;
          }
          mLastPosition = -1;
          notifyDataSetChanged();
      }
  
      /**
       * additional data;
       *
       * @param data
       */
      public void addData(List<T> data) {
          this.mData.addAll(data);
          notifyDataSetChanged();
      }
  
      public void setLoadingView(View loadingView) {
          this.mLoadingView = loadingView;
      }
  
      public List getData() {
          return mData;
      }
  
      /**
       * Get the data item associated with the specified position in the data set.
       *
       * @param position Position of the item whose data we want within the adapter's
       *                 data set.
       * @return The data at the specified position.
       */
      public T getItem(int position) {
          return mData.get(position);
      }
  
      public int getHeaderViewsCount() {
          return mHeaderView == null ? 0 : 1;
      }
  
      public int getFooterViewsCount() {
          return mFooterView == null ? 0 : 1;
      }
  
      public int getmEmptyViewCount() {
          return mEmptyView == null ? 0 : 1;
      }
  
      @Override
      public int getItemCount() {
          int i = isLoadMore() ? 1 : 0;
          int count = mData.size() + i + getHeaderViewsCount() + getFooterViewsCount();
          if (mData.size() == 0 && mEmptyView != null) {
              /**
               *  setEmptyView(false) and add emptyView
               */
              if (count == 0 && (!mHeadAndEmptyEnable || !mFootAndEmptyEnable)) {
                  count += getmEmptyViewCount();
                  /**
                   * {@link #setEmptyView(true, true, View)}
                   */
              } else if (mHeadAndEmptyEnable || mFootAndEmptyEnable) {
                  count += getmEmptyViewCount();
              }
  
              if ((mHeadAndEmptyEnable && getHeaderViewsCount() == 1 && count == 1) || count == 0) {
                  mEmptyEnable = true;
                  count += getmEmptyViewCount();
              }
  
          }
          return count;
      }
  
      @Override
      public int getItemViewType(int position) {
          /**
           * if set headView and positon =0
           */
          if (mHeaderView != null && position == 0) {
              return HEADER_VIEW;
          }
          /**
           * if user has no data and add emptyView and position <2{(headview +emptyView)}
           */
          if (mData.size() == 0 && mEmptyEnable && mEmptyView != null && position <= 2) {
              /**
               * if set {@link #setEmptyView(boolean, boolean, View)}  position = 1
               */
              if ((mHeadAndEmptyEnable || mFootAndEmptyEnable) && position == 1) {
                  /**
                   * if user want to show headview and footview and emptyView but not add headview
                   */
                  if (mHeaderView == null && mEmptyView != null && mFooterView != null) {
                      return FOOTER_VIEW;
                      /**
                       * add headview
                       */
                  } else if (mHeaderView != null && mEmptyView != null) {
                      return EMPTY_VIEW;
                  }
              } else if (position == 0) {
                  /**
                   * has no emptyView just add emptyview
                   */
                  if (mHeaderView == null) {
                      return EMPTY_VIEW;
                  } else if (mFooterView != null)
  
                      return EMPTY_VIEW;
  
  
              } else if (position == 2 && (mFootAndEmptyEnable || mHeadAndEmptyEnable) && mHeaderView != null && mEmptyView != null) {
                  return FOOTER_VIEW;
  
              } /**
               * user forget to set {@link #setEmptyView(boolean, boolean, View)}  but add footview and headview and emptyview
               */
              else if ((!mFootAndEmptyEnable || !mHeadAndEmptyEnable) && position == 1 && mFooterView != null) {
                  return FOOTER_VIEW;
              }
          } else if (mEmptyView != null && getItemCount() == (mHeadAndEmptyEnable ? 2 : 1) && mEmptyEnable) {
              return EMPTY_VIEW;
          } else if (position == mData.size() + getHeaderViewsCount()) {
              if (mNextLoadEnable)
                  return LOADING_VIEW;
              else
                  return FOOTER_VIEW;
          }
          return getDefItemViewType(position - getHeaderViewsCount());
      }
  
      protected int getDefItemViewType(int position) {
          return super.getItemViewType(position);
      }
  
      @Override
      public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
          BaseViewHolder baseViewHolder = null;
          this.mContext = parent.getContext();
          this.mLayoutInflater = LayoutInflater.from(mContext);
          switch (viewType) {
              case LOADING_VIEW:
                  baseViewHolder = getLoadingView(parent);
                  initItemClickListener(baseViewHolder);
                  break;
              case HEADER_VIEW:
                  baseViewHolder = new BaseViewHolder(mContext, mHeaderView);
                  break;
              case EMPTY_VIEW:
                  baseViewHolder = new BaseViewHolder(mContext, mEmptyView);
                  break;
              case FOOTER_VIEW:
                  baseViewHolder = new BaseViewHolder(mContext, mFooterView);
                  break;
              default:
                  baseViewHolder = onCreateDefViewHolder(parent, viewType);
                  initItemClickListener(baseViewHolder);
          }
          return baseViewHolder;
  
      }
  
      private BaseViewHolder getLoadingView(ViewGroup parent) {
          if (mLoadingView == null) {
              return createBaseViewHolder(parent, R.layout.def_loading);
          }
          return new BaseViewHolder(mContext, mLoadingView);
      }
  
      @Override
      public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
          super.onViewAttachedToWindow(holder);
          int type = holder.getItemViewType();
          if (type == EMPTY_VIEW || type == HEADER_VIEW || type == FOOTER_VIEW || type == LOADING_VIEW) {
              setFullSpan(holder);
          }
      }
  
      protected void setFullSpan(RecyclerView.ViewHolder holder) {
          if (holder.itemView.getLayoutParams() instanceof StaggeredGridLayoutManager.LayoutParams) {
              StaggeredGridLayoutManager.LayoutParams params = (StaggeredGridLayoutManager.LayoutParams) holder.itemView.getLayoutParams();
              params.setFullSpan(true);
          }
      }
  
      @Override
      public void onBindViewHolder(final RecyclerView.ViewHolder holder, int positions) {
  
          switch (holder.getItemViewType()) {
              case 0:
                  convert((BaseViewHolder) holder, mData.get(holder.getLayoutPosition() - getHeaderViewsCount()));
                  addAnimation(holder);
                  break;
              case LOADING_VIEW:
                  addLoadMore(holder);
                  break;
              case HEADER_VIEW:
                  break;
              case EMPTY_VIEW:
                  break;
              case FOOTER_VIEW:
                  break;
              default:
                  convert((BaseViewHolder) holder, mData.get(holder.getLayoutPosition() - getHeaderViewsCount()));
                  onBindDefViewHolder((BaseViewHolder) holder, mData.get(holder.getLayoutPosition() - getHeaderViewsCount()));
                  break;
          }
  
      }
  
      protected BaseViewHolder onCreateDefViewHolder(ViewGroup parent, int viewType) {
          return createBaseViewHolder(parent, mLayoutResId);
      }
  
      protected BaseViewHolder createBaseViewHolder(ViewGroup parent, int layoutResId) {
          if (mContentView == null) {
              return new BaseViewHolder(mContext, getItemView(layoutResId, parent));
          }
          return new BaseViewHolder(mContext, mContentView);
      }
  
  
      public void addHeaderView(View header) {
          this.mHeaderView = header;
          this.notifyDataSetChanged();
      }
  
      public void addFooterView(View footer) {
          mNextLoadEnable = false;
          this.mFooterView = footer;
          this.notifyDataSetChanged();
      }
  
      /**
       * Sets the view to show if the adapter is empty
       */
      public void setEmptyView(View emptyView) {
          setEmptyView(false, false, emptyView);
      }
      public void setEmptyView(boolean isHeadAndEmpty, View emptyView) {
          setEmptyView(isHeadAndEmpty, false, emptyView);
      }
      /**
       * set emptyView show if adapter is empty and want to show headview and footview
       *
       * @param isHeadAndEmpty
       * @param isFootAndEmpty
       * @param emptyView
       */
      public void setEmptyView(boolean isHeadAndEmpty, boolean isFootAndEmpty, View emptyView) {
          mHeadAndEmptyEnable = isHeadAndEmpty;
          mFootAndEmptyEnable = isFootAndEmpty;
          mEmptyView = emptyView;
          mEmptyEnable = true;
      }
      /**
       * When the current adapter is empty, the BaseQuickAdapter can display a special view
       * called the empty view. The empty view is used to provide feedback to the user
       * that no data is available in this AdapterView.
       *
       * @return The view to show if the adapter is empty.
       */
      public View getEmptyView() {
          return mEmptyView;
      }
  
      /**
       * see more {@link  public void notifyDataChangedAfterLoadMore(boolean isNextLoad)}
       *
       * @param isNextLoad
       */
      @Deprecated
      public void isNextLoad(boolean isNextLoad) {
          mNextLoadEnable = isNextLoad;
          mLoadingMoreEnable = false;
          notifyDataSetChanged();
  
      }
  
      public void notifyDataChangedAfterLoadMore(boolean isNextLoad) {
          mNextLoadEnable = isNextLoad;
          mLoadingMoreEnable = false;
          notifyDataSetChanged();
  
      }
  
      public void notifyDataChangedAfterLoadMore(List<T> data, boolean isNextLoad) {
          mData.addAll(data);
          notifyDataChangedAfterLoadMore(isNextLoad);
      }
  
  
      private void addLoadMore(RecyclerView.ViewHolder holder) {
          if (isLoadMore() && !mLoadingMoreEnable) {
              mLoadingMoreEnable = true;
              mRequestLoadMoreListener.onLoadMoreRequested();
          }
      }
  
      private void initItemClickListener(final BaseViewHolder baseViewHolder) {
          if (onRecyclerViewItemClickListener != null) {
              baseViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                      onRecyclerViewItemClickListener.onItemClick(v, baseViewHolder.getLayoutPosition() - getHeaderViewsCount());
                  }
              });
          }
          if (onRecyclerViewItemLongClickListener != null) {
              baseViewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                  @Override
                  public boolean onLongClick(View v) {
                      return onRecyclerViewItemLongClickListener.onItemLongClick(v, baseViewHolder.getLayoutPosition() - getHeaderViewsCount());
                  }
              });
          }
      }
  
      private void addAnimation(RecyclerView.ViewHolder holder) {
          if (mOpenAnimationEnable) {
              if (!mFirstOnlyEnable || holder.getLayoutPosition() > mLastPosition) {
                  BaseAnimation animation = null;
                  if (mCustomAnimation != null) {
                      animation = mCustomAnimation;
                  } else {
                      animation = mSelectAnimation;
                  }
                  for (Animator anim : animation.getAnimators(holder.itemView)) {
                      startAnim(anim, holder.getLayoutPosition());
                  }
                  mLastPosition = holder.getLayoutPosition();
              }
          }
      }
  
      protected void startAnim(Animator anim, int index) {
          anim.setDuration(mDuration).start();
          anim.setInterpolator(mInterpolator);
      }
  
      private boolean isLoadMore() {
          return mNextLoadEnable && pageSize != -1 && mRequestLoadMoreListener != null && mData.size() >= pageSize;
      }
  
      protected View getItemView(int layoutResId, ViewGroup parent) {
          return mLayoutInflater.inflate(layoutResId, parent, false);
      }
  
  
      /**
       * @see #convert(BaseViewHolder, Object) ()
       * @deprecated This method is deprecated
       * {@link #convert(BaseViewHolder, Object)} depending on your use case.
       */
      @Deprecated
      protected void onBindDefViewHolder(BaseViewHolder holder, T item) {
      }
  
      public interface RequestLoadMoreListener {
  
          void onLoadMoreRequested();
      }
  
  
      /**
       * Set the view animation type.
       *
       * @param animationType One of {@link #ALPHAIN}, {@link #SCALEIN}, {@link #SLIDEIN_BOTTOM}, {@link #SLIDEIN_LEFT}, {@link #SLIDEIN_RIGHT}.
       */
      public void openLoadAnimation(@AnimationType int animationType) {
          this.mOpenAnimationEnable = true;
          mCustomAnimation = null;
          switch (animationType) {
              case ALPHAIN:
                  mSelectAnimation = new AlphaInAnimation();
                  break;
              case SCALEIN:
                  mSelectAnimation = new ScaleInAnimation();
                  break;
              case SLIDEIN_BOTTOM:
                  mSelectAnimation = new SlideInBottomAnimation();
                  break;
              case SLIDEIN_LEFT:
                  mSelectAnimation = new SlideInLeftAnimation();
                  break;
              case SLIDEIN_RIGHT:
                  mSelectAnimation = new SlideInRightAnimation();
                  break;
              case SLIDEIN_CUSTOM:
                  mSelectAnimation = new CustomAnimation();
                  break;
              default:
                  break;
          }
      }
  
      /**
       * Set Custom ObjectAnimator
       *
       * @param animation ObjectAnimator
       */
      public void openLoadAnimation(BaseAnimation animation) {
          this.mOpenAnimationEnable = true;
          this.mCustomAnimation = animation;
      }
  
      public void openLoadAnimation() {
          this.mOpenAnimationEnable = true;
      }
  
  
      public void isFirstOnly(boolean firstOnly) {
          this.mFirstOnlyEnable = firstOnly;
      }
  
      /**
       * Implement this method and use the helper to adapt the view to the given item.
       *
       * @param helper A fully initialized helper.
       * @param item   The item that needs to be displayed.
       */
      protected abstract void convert(BaseViewHolder helper, T item);
  
  
      @Override
      public long getItemId(int position) {
          return position;
      }
  
  
  }
  