Skip to content

Instantly share code, notes, and snippets.

@kalpeshp0310
Created November 7, 2016 10:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kalpeshp0310/5a56a7b598964690b1bbc217f99af90b to your computer and use it in GitHub Desktop.
Save kalpeshp0310/5a56a7b598964690b1bbc217f99af90b to your computer and use it in GitHub Desktop.
SectionedRecyclerViewAdapter
import android.support.annotation.Nullable;
import android.support.v4.util.ArrayMap;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.ViewGroup;
import java.util.List;
public abstract class SectionedRecyclerViewAdapter<VH extends RecyclerView.ViewHolder>
extends RecyclerView.Adapter<VH> {
private final static int VIEW_TYPE_HEADER = 0;
private final static int VIEW_TYPE_ITEM = 1;
private final ArrayMap<Integer, Integer> mHeaderLocationMap;
private GridLayoutManager mLayoutManager;
public SectionedRecyclerViewAdapter() {
mHeaderLocationMap = new ArrayMap<>();
}
public abstract int getSectionCount();
public abstract int getItemCount(int section);
public abstract VH onCreateViewHolder(ViewGroup parent, boolean header);
public abstract void onBindHeaderViewHolder(VH holder, int section);
public void onBindHeaderViewHolder(VH holder, int section, List<Object> payload) {
onBindHeaderViewHolder(holder, section);
}
public abstract void onBindViewHolder(VH holder, int section, int relativePosition,
int absolutePosition, int adapterPosition);
public void onBindViewHolder(VH holder, int section, int relativePosition, int absolutePosition,
int adapterPosition, List<Object> payload) {
onBindViewHolder(holder, section, relativePosition, absolutePosition, adapterPosition);
}
public final boolean isHeader(int position) {
return mHeaderLocationMap.get(position) != null;
}
public final void setLayoutManager(@Nullable GridLayoutManager lm) {
mLayoutManager = lm;
if (lm == null) return;
lm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override public int getSpanSize(int position) {
if (isHeader(position)) return mLayoutManager.getSpanCount();
return 1;
}
});
}
// returns section along with offsetted position
public int[] getSectionIndexAndRelativePosition(int itemPosition) {
synchronized (mHeaderLocationMap) {
Integer lastSectionIndex = -1;
for (final Integer sectionIndex : mHeaderLocationMap.keySet()) {
if (itemPosition > sectionIndex) {
lastSectionIndex = sectionIndex;
} else {
break;
}
lastSectionIndex = sectionIndex;
}
return new int[] {
mHeaderLocationMap.get(lastSectionIndex), itemPosition - lastSectionIndex - 1
};
}
}
@Override public final int getItemCount() {
int count = 0;
mHeaderLocationMap.clear();
for (int s = 0; s < getSectionCount(); s++) {
mHeaderLocationMap.put(count, s);
count += getItemCount(s) + 1;
}
return count;
}
/**
* @hide
* @deprecated
*/
@Override @Deprecated public final VH onCreateViewHolder(ViewGroup parent, int viewType) {
return onCreateViewHolder(parent, viewType == VIEW_TYPE_HEADER);
}
/**
* @hide
* @deprecated
*/
@Deprecated @Override public final int getItemViewType(int position) {
if (isHeader(position)) {
return VIEW_TYPE_HEADER;
} else {
return VIEW_TYPE_ITEM;
}
}
/**
* @hide
* @deprecated
*/
@Override @Deprecated public final void onBindViewHolder(VH holder, int position) {
//Not implemented.
}
/**
* @hide
* @deprecated
*/
@Deprecated @Override public final void onBindViewHolder(VH holder, int position,
List<Object> payloads) {
StaggeredGridLayoutManager.LayoutParams layoutParams = null;
if (holder.itemView.getLayoutParams() instanceof GridLayoutManager.LayoutParams) {
layoutParams =
new StaggeredGridLayoutManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
} else if (holder.itemView.getLayoutParams() instanceof StaggeredGridLayoutManager.LayoutParams) {
layoutParams = (StaggeredGridLayoutManager.LayoutParams) holder.itemView.getLayoutParams();
}
if (isHeader(position)) {
if (layoutParams != null) layoutParams.setFullSpan(true);
onBindHeaderViewHolder(holder, mHeaderLocationMap.get(position), payloads);
} else {
if (layoutParams != null) layoutParams.setFullSpan(false);
final int[] sectionAndPos = getSectionIndexAndRelativePosition(position);
onBindViewHolder(holder, sectionAndPos[0],
// offset section view positions
sectionAndPos[1], position - (sectionAndPos[0] + 1), position, payloads);
}
if (layoutParams != null) holder.itemView.setLayoutParams(layoutParams);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment