package com.shizhefei.recyclerview; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.ViewHolder; import android.support.v7.widget.StaggeredGridLayoutManager; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnLongClickListener; import android.view.ViewGroup; import android.widget.FrameLayout; import java.util.ArrayList; import java.util.List; public abstract class HFAdapter extends RecyclerView.Adapter { public static final int TYPE_MANAGER_OTHER = 0; public static final int TYPE_MANAGER_LINEAR = 1; public static final int TYPE_MANAGER_GRID = 2; public static final int TYPE_MANAGER_STAGGERED_GRID = 3; public static final int TYPE_HEADER = 7898; public static final int TYPE_FOOTER = 7899; private List<View> mHeaders = new ArrayList<View>(); private List<View> mFooters = new ArrayList<View>(); private boolean needSetClickListener = true; public HFAdapter() { this(true); } public HFAdapter(boolean needSetClickListener) { this.needSetClickListener = needSetClickListener; } private int mManagerType; public int getHeadSize() { return mHeaders.size(); } public int getFootSize() { return mFooters.size(); } public int getManagerType() { return mManagerType; } public void notifyDataSetChangedHF() { notifyDataSetChanged(); } public void notifyItemChangedHF(int position) { notifyItemChanged(getRealPosition(position)); } public void notifyItemMovedHF(int fromPosition, int toPosition) { notifyItemMoved(getRealPosition(fromPosition), getRealPosition(toPosition)); } public void notifyItemRangeChangedHF(int positionStart, int itemCount) { notifyItemRangeChanged(getRealPosition(positionStart), itemCount); } public void notifyItemRangeRemovedHF(int positionStart, int itemCount) { notifyItemRangeRemoved(getRealPosition(positionStart), itemCount); } public void notifyItemRemovedHF(int position) { notifyItemRemoved(getRealPosition(position)); } public void notifyItemInsertedHF(int position) { notifyItemInserted(getRealPosition(position)); } public void notifyItemRangeInsertedHF(int positionStart, int itemCount) { notifyItemRangeInserted(getRealPosition(positionStart), itemCount); } @Override public final long getItemId(int position) { return getItemIdHF(getRealPosition(position)); } public long getItemIdHF(int position) { return super.getItemId(position); } public abstract ViewHolder onCreateViewHolderHF(ViewGroup viewGroup, int type); @Override public final ViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) { // if our position is one of our items (this comes from // getItemViewType(int position) below) if (type != TYPE_HEADER && type != TYPE_FOOTER) { ViewHolder vh = onCreateViewHolderHF(viewGroup, type); return vh; // else we have a header/footer } else { // createExecutor a new framelayout, or inflate from a resource FrameLayout frameLayout = new FrameLayout(viewGroup.getContext()); // make sure it fills the space frameLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); return new HeaderFooterViewHolder(frameLayout); } } @Override public final void onBindViewHolder(final ViewHolder vh, int position) { // check what type of view our position is if (isHeader(position)) { View v = mHeaders.get(position); // add our view to a header view and display it prepareHeaderFooter((HeaderFooterViewHolder) vh, v); } else if (isFooter(position)) { View v = mFooters.get(position - getItemCountHF() - mHeaders.size()); // add our view to a footer view and display it prepareHeaderFooter((HeaderFooterViewHolder) vh, v); } else { if (needSetClickListener) { vh.itemView.setOnClickListener(new MyOnClickListener(vh)); vh.itemView.setOnLongClickListener(new MyOnLongClickListener(vh)); } // it's one of our items, display as required onBindViewHolderHF(vh, getRealPosition(position)); } } @Override public final void onBindViewHolder(ViewHolder holder, int position, List payloads) { super.onBindViewHolder(holder, position, payloads); } public int getRealPosition(int position) { return position - mHeaders.size(); } public abstract void onBindViewHolderHF(ViewHolder vh, int position); private boolean isHeader(int position) { return (position < mHeaders.size()); } public boolean isHeader(ViewHolder viewHolder) { return isHeader(viewHolder.getAdapterPosition()); } public boolean isFooter(ViewHolder viewHolder) { return isFooter(viewHolder.getAdapterPosition()); } private void prepareHeaderFooter(HeaderFooterViewHolder vh, View view) { // if it's a staggered grid, span the whole layout if (mManagerType == TYPE_MANAGER_STAGGERED_GRID) { StaggeredGridLayoutManager.LayoutParams layoutParams = new StaggeredGridLayoutManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); layoutParams.setFullSpan(true); vh.itemView.setLayoutParams(layoutParams); } // if the view already belongs to another layout, remove it if (view.getParent() != null) { ((ViewGroup) view.getParent()).removeView(view); } // empty out our FrameLayout and replace with our header/footer vh.base.removeAllViews(); vh.base.addView(view); } private boolean isFooter(int position) { return (position >= mHeaders.size() + getItemCountHF()); } @Override public final int getItemCount() { return mHeaders.size() + getItemCountHF() + mFooters.size(); } public abstract int getItemCountHF(); @Override public final int getItemViewType(int position) { // check what type our position is, based on the assumption that the // order is headers > items > footers if (isHeader(position)) { return TYPE_HEADER; } else if (isFooter(position)) { return TYPE_FOOTER; } int type = getItemViewTypeHF(getRealPosition(position)); if (type == TYPE_HEADER || type == TYPE_FOOTER) { throw new IllegalArgumentException("Item type cannot equal " + TYPE_HEADER + " or " + TYPE_FOOTER); } return type; } public int getItemViewTypeHF(int position) { return super.getItemViewType(position); } // add a header to the adapter public void addHeader(View header) { if (!mHeaders.contains(header)) { mHeaders.add(header); // animate notifyItemInserted(mHeaders.size() - 1); } } // remove a header from the adapter public void removeHeader(View header) { if (mHeaders.contains(header)) { // animate notifyItemRemoved(mHeaders.indexOf(header)); mHeaders.remove(header); } } // add a footer to the adapter public void addFooter(View footer) { if (!mFooters.contains(footer)) { mFooters.add(footer); // animate notifyItemInserted(mHeaders.size() + getItemCountHF() + mFooters.size() - 1); } } // remove a footer from the adapter public void removeFooter(View footer) { if (mFooters.contains(footer)) { // animate notifyItemRemoved(mHeaders.size() + getItemCountHF() + mFooters.indexOf(footer)); mFooters.remove(footer); } } // our header/footer RecyclerView.ViewHolder is just a FrameLayout public static class HeaderFooterViewHolder extends ViewHolder { FrameLayout base; public HeaderFooterViewHolder(View itemView) { super(itemView); base = (FrameLayout) itemView; } } public OnItemClickListener getOnItemClickListener() { return onItemClickListener; } public void setOnItemClickListener(OnItemClickListener onItemClickListener) { this.onItemClickListener = onItemClickListener; Log.d("eeee", "setOnItemClickListener " + this.onItemClickListener); } public OnItemLongClickListener getOnItemLongClickListener() { return onItemLongClickListener; } public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener) { this.onItemLongClickListener = onItemLongClickListener; } private OnItemClickListener onItemClickListener; private OnItemLongClickListener onItemLongClickListener; private class MyOnClickListener implements OnClickListener { private ViewHolder vh; public MyOnClickListener(ViewHolder vh) { super(); this.vh = vh; } @Override public void onClick(View v) { int position = getRealPosition(vh.getLayoutPosition()); if (!onItemClick(vh, position)) { if (HFAdapter.this.onItemClickListener != null) { HFAdapter.this.onItemClickListener.onItemClick(HFAdapter.this, vh, position); } } } } private class MyOnLongClickListener implements OnLongClickListener { private ViewHolder vh; public MyOnLongClickListener(ViewHolder vh) { super(); this.vh = vh; } @Override public boolean onLongClick(View v) { int position = getRealPosition(vh.getLayoutPosition()); if (!onItemLongClick(vh, position)) { if (HFAdapter.this.onItemLongClickListener != null) { HFAdapter.this.onItemLongClickListener.onItemLongClick(HFAdapter.this, vh, position); } } return true; } } /** * 直接在Adapter里面处理项的点击事件 * * @param vh * @param position * @return 如果返回true,事件就被拦截不再调用onItemClickListener,否则会调用onItemClickListener */ protected boolean onItemClick(ViewHolder vh, int position) { return false; } /** * 直接在Adapter里面处理项的长按事件 * * @param vh ViewHolder * @param position item位置 * @return 如果返回true,事件就被拦截不再调用onItemLongClickListener,否则会调用onItemLongClickListener */ protected boolean onItemLongClick(ViewHolder vh, int position) { return false; } public static interface OnItemClickListener { void onItemClick(HFAdapter adapter, ViewHolder vh, int position); } public static interface OnItemLongClickListener { void onItemLongClick(HFAdapter adapter, ViewHolder vh, int position); } public void setmManagerType(int mManagerType) { this.mManagerType = mManagerType; } }