content: package cn.jake.share.frdialog.recyclerview.wrap;
  
  import androidx.annotation.NonNull;
  import androidx.recyclerview.widget.GridLayoutManager;
  import androidx.recyclerview.widget.RecyclerView;
  import android.util.SparseArray;
  import android.view.View;
  import android.view.ViewGroup;
  
  import cn.jake.share.frdialog.recyclerview.FRBaseDialogAdapter;
  import cn.jake.share.frdialog.recyclerview.FRBaseDialogViewHolder;
  import cn.jake.share.frdialog.recyclerview.interfaces.RecyclerOnItemClickListener;
  import cn.jake.share.frdialog.recyclerview.interfaces.RecyclerOnItemLongClickListener;
  
  /**
   * Created by Jack
   * Date：2018/9/11 下午2:03
   * Desc：
   */
  public class WrapRecyclerAdapter extends RecyclerView.Adapter<FRBaseDialogViewHolder> {
  
      private SparseArray<View> mHeaderViews;   //存放所有头部
      private SparseArray<View> mFooterViews;   //存放所有尾部
  
      // 基本的头部类型开始位置  用于viewType
      public static int BASE_ITEM_TYPE_HEADER = 100000;
      // 基本的底部类型开始位置  用于viewType
      public static int BASE_ITEM_TYPE_FOOTER = 200000;
  
      // 列表的Adapter
      private FRBaseDialogAdapter mAdapter;
  
      public WrapRecyclerAdapter(FRBaseDialogAdapter adapter) {
          this.mAdapter = adapter;
          mHeaderViews = new SparseArray<>();
          mFooterViews = new SparseArray<>();
      }
  
      @NonNull
      @Override
      public FRBaseDialogViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
          // viewType 可能就是 SparseArray 的key
          if (isHeaderViewType(viewType)) {
              View headerView = mHeaderViews.get(viewType);
              return createHeaderFooterViewHolder(headerView);
          }
          if (isFooterViewType(viewType)) {
              View footerView = mFooterViews.get(viewType);
              return createHeaderFooterViewHolder(footerView);
          }
          return mAdapter.onCreateViewHolder(parent, viewType);
      }
  
      /**
       * 是不是底部类型
       */
      private boolean isFooterViewType(int viewType) {
          int position = mFooterViews.indexOfKey(viewType);
          return position >= 0;
      }
  
      /**
       * 创建头部或者底部的ViewHolder
       */
      private FRBaseDialogViewHolder createHeaderFooterViewHolder(View view) {
          return new FRBaseDialogViewHolder(view) {
  
          };
      }
  
      /**
       * 是不是头部类型
       */
      private boolean isHeaderViewType(int viewType) {
          int position = mHeaderViews.indexOfKey(viewType);
          return position >= 0;
      }
  
      @Override
      public void onBindViewHolder(@NonNull FRBaseDialogViewHolder holder, int position) {
          if (isHeaderPosition(position) || isFooterPosition(position)) {
              return;
          }
          // 计算一下位置
          position = position - mHeaderViews.size();
          mAdapter.onBindViewHolder(holder, position);
      }
  
      @Override
      public int getItemViewType(int position) {
          if (isHeaderPosition(position)) {
              // 直接返回position位置的key
              return mHeaderViews.keyAt(position);
          }
          if (isFooterPosition(position)) {
              // 直接返回position位置的key
              position = position - mHeaderViews.size() - mAdapter.getItemCount();
              return mFooterViews.keyAt(position);
          }
          // 返回列表Adapter的getItemViewType
          position = position - mHeaderViews.size();
          return mAdapter.getItemViewType(position);
      }
  
      /**
       * 是不是底部位置
       */
      private boolean isFooterPosition(int position) {
          return position >= (mHeaderViews.size() + mAdapter.getItemCount());
      }
  
      /**
       * 是不是头部位置
       */
      private boolean isHeaderPosition(int position) {
          return position < mHeaderViews.size();
      }
  
      @Override
      public int getItemCount() {
          // 条数三者相加 = 底部条数 + 头部条数 + Adapter的条数
          return mAdapter.getItemCount() + mHeaderViews.size() + mFooterViews.size();
      }
  
      /**
       * 获取列表的Adapter
       */
      private RecyclerView.Adapter getAdapter() {
          return mAdapter;
      }
  
      // 添加头部
      public void addHeaderView(View view) {
          int position = mHeaderViews.indexOfValue(view);
          if (position < 0) {
              mHeaderViews.put(BASE_ITEM_TYPE_HEADER++, view);
          }
          notifyDataSetChanged();
      }
  
      // 添加底部
      public void addFooterView(View view) {
          int position = mFooterViews.indexOfValue(view);
          if (position < 0) {
              mFooterViews.put(BASE_ITEM_TYPE_FOOTER++, view);
          }
          notifyDataSetChanged();
      }
  
      // 移除头部
      public void removeHeaderView(View view) {
          int index = mHeaderViews.indexOfValue(view);
          if (index < 0) return;
          mHeaderViews.removeAt(index);
          notifyDataSetChanged();
      }
  
      // 移除底部
      public void removeFooterView(View view) {
          int index = mFooterViews.indexOfValue(view);
          if (index < 0) return;
          mFooterViews.removeAt(index);
          notifyDataSetChanged();
      }
  
      public void setOnItemClickListener(RecyclerOnItemClickListener onItemClickListener) {
          mAdapter.setOnItemClickListener(onItemClickListener);
      }
  
      public void setOnItemLongClickListener(RecyclerOnItemLongClickListener onItemLongClickListener) {
          mAdapter.setOnItemLongClickListener(onItemLongClickListener);
      }
  
      /**
       * 解决GridLayoutManager添加头部和底部不占用一行的问题
       */
      public void adjustSpanSize(RecyclerView recycler) {
          if (recycler.getLayoutManager() instanceof GridLayoutManager) {
              final GridLayoutManager layoutManager = (GridLayoutManager) recycler.getLayoutManager();
              layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                  @Override
                  public int getSpanSize(int position) {
                      boolean isHeaderOrFooter = isHeaderPosition(position) || isFooterPosition(position);
                      return isHeaderOrFooter ? layoutManager.getSpanCount() : 1;
                  }
              });
          }
      }
  }