public abstract class MultiLayoutRecyclerAdapter extends RecyclerView.Adapter {

   public static final int TYPE_FLAG = 1000;
   public static final int TYPE_NORMAL = 1;

   @LayoutRes
   private int layoutRes;

   private Context mContext;

   private List<T> mDatas = new ArrayList<>();

   private List<Integer> mHeaderViewTypes = new ArrayList<>();
   private List<Integer> mFooterViewTypes = new ArrayList<>();

   private List<HeaderRes> mHeaderViews = new ArrayList<>();
   private List<FooterRes> mFooterViews = new ArrayList<>();

   private AdapterItemClickListener mAdapterItemClickListener;
   private final int NO_HAS = -1001;
   private final int HAS = -1002;


   public MultiLayoutRecyclerAdapter(@LayoutRes int layoutRes, Context context, List<T> datas) {
          this.layoutRes = layoutRes;
          this.mContext = context;
          this.mDatas = datas;
   }

   @Override
   public MultiLayoutViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

          if (mHeaderViewTypes.contains(viewType)) {
                 return new MultiLayoutViewHolder(mContext, mHeaderViews.get(viewType / TYPE_FLAG).getmView());
          }

          if (mFooterViewTypes.contains(viewType)) {
                 int typeIndex = viewType / TYPE_FLAG - mDatas.size() - mHeaderViews.size();
                 return new MultiLayoutViewHolder(mContext, mFooterViews.get(typeIndex).getmView());
          }

          return new MultiLayoutViewHolder(mContext, LayoutInflater.from(mContext).inflate(layoutRes, parent, false));
   }

   @Override
   public void onBindViewHolder(MultiLayoutViewHolder holder, final int position) {

          if (isHeaderPosition(position)) {
                 onBindHeaderView(holder, mHeaderViews.get(position).getmLayoutRes());
                 return;
          }

          if (isFooterPosition(position)) {
                 onBinFooterView(holder, mFooterViews.get(position - (getItemCount() - mFooterViews.size())).getmLayoutRes());
                 return;
          }

          int realPosition = getRealPosition(position);
          if (realPosition < mDatas.size()) {
                 final T data = mDatas.get(realPosition);
                 onBindBodyView(holder, data, realPosition);
                 holder.mItemView.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                               if(mAdapterItemClickListener ! = null) { mAdapterItemClickListener.adapterItemClick(data, position); }}}); } } public void setmAdapterItemClickListener(AdapterItemClickListener mAdapterItemClick) { this.mAdapterItemClickListener = mAdapterItemClick; } public interface AdapterItemClickListener<T> { void adapterItemClick(T data, int position); } public abstract void onBindBodyView(MultiLayoutViewHolder holder, T data, int realPosition); private int getRealPosition(int position) {return position - mHeaderViews.size();
   }

   public void onBinFooterView(MultiLayoutViewHolder holder, int layoutRes) {

   }

   public void onBindHeaderView(MultiLayoutViewHolder holder, int layoutRes) {

   }

   private boolean isFooterPosition(int position) {
          if (mFooterViews.size() > 0 && position >= getItemCount() - mFooterViews.size() && position < getItemCount()) {
                 return true;
          }
          return false;
   }

   private boolean isHeaderPosition(int position) {
          if (mHeaderViews.size() > 0 && position < mHeaderViews.size()) {
                 return true;
          }
          return false;
   }

   @Override
   public int getItemCount() {
          return mDatas.size() + mHeaderViews.size() + mFooterViews.size();
   }

   @Override
   public int getItemViewType(int position) {
          if (mHeaderViews.size() > 0 && position < mHeaderViews.size()) {
                 mHeaderViewTypes.add(position * TYPE_FLAG);
                 return position * TYPE_FLAG;
          }

          if (mFooterViews.size() > 0 && position >= getItemCount() - mFooterViews.size() && position < getItemCount()) {
                 mFooterViewTypes.add(position * TYPE_FLAG);
                 return position * TYPE_FLAG;
          }
          return TYPE_NORMAL;
   }


   public void addHeaderView(@LayoutRes int layoutRes) {
          int position = isHasHeaderRes(layoutRes);
          if (position == HAS) {
                 return; } View view = View.inflate(mContext, layoutRes, null); ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); view.setLayoutParams(lp); HeaderRes headerRes = new HeaderRes(view, layoutRes); mHeaderViews.add(headerRes); } /** * TODO add no network, * * @param layoutRes */ public void addStateView(@layoutRes int layoutRes) {int position = isHasHeaderRes(layoutRes);if (position == HAS) {
                 return;
          }

          View view = View.inflate(mContext, layoutRes, null);
          ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
          view.setLayoutParams(lp);
          HeaderRes headerRes = new HeaderRes(view, layoutRes);
          mHeaderViews.add(headerRes);
   }

   public void addFooterView(@LayoutRes int layoutRes) {
          int position = isHasFooterRes(layoutRes);
          if (position == HAS) {
                 return;
          }

          View view = View.inflate(mContext, layoutRes, null);
          ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
          view.setLayoutParams(lp);
          FooterRes footerRes = new FooterRes(view, layoutRes);
          mFooterViews.add(footerRes);
   }

   public void removeFooterView(@LayoutRes int layoutRes) {
          int position = isHasFooterRes(layoutRes);
          if (position == HAS) {
                 mFooterViews.remove(mFooterViews.get(position));
          }
   }

   public void removeHeaderView(@LayoutRes int layoutRes) {
          int position = isHasHeaderRes(layoutRes);
          if (position == HAS) {
                 mHeaderViews.remove(mHeaderViews.get(position));
          }
   }


   private int isHasHeaderRes(@LayoutRes int layoutRes) {
          for (int i = 0; i < mHeaderViews.size(); i++) {
                 if (mHeaderViews.get(i).getmLayoutRes() == layoutRes) {
                        returnHAS; }}return NO_HAS;
   }

   private int isHasFooterRes(@LayoutRes int layoutRes) {
          for (int i = 0; i < mFooterViews.size(); i++) {
                 if (mFooterViews.get(i).getmLayoutRes() == layoutRes) {
                        returnHAS; }}return NO_HAS;
   }

   @Override
   public void onAttachedToRecyclerView(RecyclerView recyclerView) {
          super.onAttachedToRecyclerView(recyclerView);
          RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
          if (manager instanceof GridLayoutManager) {
                 final GridLayoutManager gridLayoutManager = (GridLayoutManager) manager;
                 gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                        @Override
                        public int getSpanSize(int position) {
                               if (isHeaderPosition(position) || isFooterPosition(position)) {
                                      return gridLayoutManager.getSpanCount();
                               } else {
                                      return1; }}}); } } @Override public void onViewAttachedToWindow(MultiLayoutViewHolder holder) { super.onViewAttachedToWindow(holder); ViewGroup.LayoutParams params = holder.mItemView.getLayoutParams();if (params != null && params instanceof StaggeredGridLayoutManager.LayoutParams) {
                 StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) params;
                 layoutParams.setFullSpan(isHeaderPosition(holder.getLayoutPosition()) || isFooterPosition(holder.getLayoutPosition()));
          }
   }Copy the code

}

public class MultiLayoutViewHolder extends RecyclerView.ViewHolder {

public View mItemView;

private Context mContext; private SparseArray<View> mViews; public MultiLayoutViewHolder(Context context, View itemView) { super(itemView); this.mContext = context; mViews = new SparseArray<>(); this.mItemView = itemView; //// FIXME: 2017/9/7 Adaptive handling autoutils.autosize (this.mitemview); } public <T extends View> T getView(@IdRes int resId) { View view = mViews.get(resId);if (null == view) {
                 view = mItemView.findViewById(resId);
                 mViews.append(resId, view);
          }

          return (T) view;
   }

   public MultiLayoutViewHolder setViewText(@IdRes int resId, String text) {
          TextView textView = getView(resId);
          textView.setText(TextUtils.isEmpty(text) ? "" : text);
          return this;
   }

   public MultiLayoutViewHolder setImageDrawable(@IdRes int resId, @DrawableRes int drawableRes) {
          ImageView imageView = getView(resId);
          imageView.setImageDrawable(ContextCompat.getDrawable(mContext, drawableRes));
          return this;
   }


   public MultiLayoutViewHolder setOnClickListener(@IdRes int resId, View.OnClickListener clickListener){
          View view = getView(resId);
          view.setOnClickListener(clickListener);
          return this;
   }Copy the code

}

public class FooterRes {

private View mView;

   private
   @LayoutRes
   int mLayoutRes;

   public FooterRes(View mView, int mLayoutRes) {
          this.mView = mView;
          this.mLayoutRes = mLayoutRes;
   }

   public View getmView() {
          return mView;
   }

   public void setmView(View mView) {
          this.mView = mView;
   }

   public int getmLayoutRes() {
          return mLayoutRes;
   }

   public void setmLayoutRes(int mLayoutRes) {
          this.mLayoutRes = mLayoutRes;
   }Copy the code

}

public class HeaderRes {

private View mView;

private

@LayoutRes

int mLayoutRes;

   public HeaderRes(View mView, int mLayoutRes) {
          this.mView = mView;
          this.mLayoutRes = mLayoutRes;
   }

   public View getmView() {
          return mView;
   }

   public void setmView(View mView) {
          this.mView = mView;
   }

   public int getmLayoutRes() {
          return mLayoutRes;
   }

   public void setmLayoutRes(int mLayoutRes) {
          this.mLayoutRes = mLayoutRes;
   }Copy the code

}