123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- /**
- * Copyright 2016 Aidan Follestad
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
- * either express or implied. See the License for the specific language
- * governing permissions and limitations under the License.
- */
- package com.afollestad.sectionedrecyclerview;
- import android.support.annotation.IntRange;
- 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;
- /**
- * @author Aidan Follestad (afollestad)
- */
- public abstract class SectionedRecyclerViewAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
- protected final static int VIEW_TYPE_HEADER = -2;
- protected final static int VIEW_TYPE_ITEM = -1;
- private final ArrayMap<Integer, Integer> mHeaderLocationMap;
- private GridLayoutManager mLayoutManager;
- private ArrayMap<Integer, Integer> mSpanMap;
- private boolean mShowHeadersForEmptySections;
- public SectionedRecyclerViewAdapter() {
- mHeaderLocationMap = new ArrayMap<>();
- }
- public abstract int getSectionCount();
- public abstract int getItemCount(int section);
- public abstract void onBindHeaderViewHolder(VH holder, int section);
- public abstract void onBindViewHolder(VH holder, int section, int relativePosition, int absolutePosition);
- public final boolean isHeader(int position) {
- return mHeaderLocationMap.get(position) != null;
- }
- /**
- * Instructs the list view adapter to whether show headers for empty sections or not.
- *
- * @param show flag indicating whether headers for empty sections ought to be shown.
- */
- public final void shouldShowHeadersForEmptySections(boolean show) {
- mShowHeadersForEmptySections = show;
- }
- 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();
- final int[] sectionAndPos = getSectionIndexAndRelativePosition(position);
- final int absPos = position - (sectionAndPos[0] + 1);
- return getRowSpan(mLayoutManager.getSpanCount(),
- sectionAndPos[0], sectionAndPos[1], absPos);
- }
- });
- }
- @SuppressWarnings("UnusedParameters")
- protected int getRowSpan(int fullSpanSize, int section, int relativePosition, int absolutePosition) {
- return 1;
- }
- // returns section along with offsetted position
- private int[] getSectionIndexAndRelativePosition(int itemPosition) {
- synchronized (mHeaderLocationMap) {
- Integer lastSectionIndex = -1;
- for (final Integer sectionIndex : mHeaderLocationMap.keySet()) {
- if (itemPosition > sectionIndex) {
- lastSectionIndex = sectionIndex;
- } else {
- break;
- }
- }
- 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++) {
- int itemCount = getItemCount(s);
- if (mShowHeadersForEmptySections || (itemCount > 0)) {
- mHeaderLocationMap.put(count, s);
- count += itemCount + 1;
- }
- }
- return count;
- }
- /**
- * @hide
- * @deprecated
- */
- @Override
- @Deprecated
- public final int getItemViewType(int position) {
- if (isHeader(position)) {
- return getHeaderViewType(mHeaderLocationMap.get(position));
- } else {
- final int[] sectionAndPos = getSectionIndexAndRelativePosition(position);
- return getItemViewType(sectionAndPos[0],
- // offset section view positions
- sectionAndPos[1],
- position - (sectionAndPos[0] + 1));
- }
- }
- @SuppressWarnings("UnusedParameters")
- @IntRange(from = 0, to = Integer.MAX_VALUE)
- public int getHeaderViewType(int section) {
- //noinspection ResourceType
- return VIEW_TYPE_HEADER;
- }
- @SuppressWarnings("UnusedParameters")
- @IntRange(from = 0, to = Integer.MAX_VALUE)
- public int getItemViewType(int section, int relativePosition, int absolutePosition) {
- //noinspection ResourceType
- return VIEW_TYPE_ITEM;
- }
- /**
- * @hide
- * @deprecated
- */
- @Override
- @Deprecated
- public final void onBindViewHolder(VH holder, int position) {
- StaggeredGridLayoutManager.LayoutParams layoutParams = null;
- if (holder.itemView.getLayoutParams() instanceof GridLayoutManager.LayoutParams)
- layoutParams = new StaggeredGridLayoutManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
- 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));
- } else {
- if (layoutParams != null) layoutParams.setFullSpan(false);
- final int[] sectionAndPos = getSectionIndexAndRelativePosition(position);
- final int absPos = position - (sectionAndPos[0] + 1);
- onBindViewHolder(holder, sectionAndPos[0],
- // offset section view positions
- sectionAndPos[1], absPos);
- }
- if (layoutParams != null)
- holder.itemView.setLayoutParams(layoutParams);
- }
- /**
- * @hide
- * @deprecated
- */
- @Deprecated
- @Override
- public final void onBindViewHolder(VH holder, int position, List<Object> payloads) {
- super.onBindViewHolder(holder, position, payloads);
- }
- }
|