Created
June 1, 2016 21:33
-
-
Save chantellosejo/947f5eb5eed4fc9af3f3221f48964308 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.yourpackage.android; | |
import android.content.Context; | |
import android.support.annotation.CallSuper; | |
import android.support.annotation.IdRes; | |
import android.support.v7.widget.RecyclerView; | |
import android.support.v7.widget.StaggeredGridLayoutManager; | |
import android.view.LayoutInflater; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.widget.FrameLayout; | |
import com.yourpackage.android.R; | |
import java.util.ArrayList; | |
/** | |
* Handles putting headers and footers on a recyclerview | |
*/ | |
public abstract class BaseRecyclerViewAdapter<T extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<RecyclerView.ViewHolder> { | |
LayoutInflater inflater; | |
private final ArrayList<View> headerViews; | |
private final ArrayList<View> footerViews; | |
private boolean headerShouldSpanView = true; | |
private boolean footerShouldSpanView = true; | |
private final int headerViewType; | |
private final int footerViewType; | |
@CallSuper | |
public void addHeaderView(View headerView) { | |
this.headerViews.add(headerView); | |
} | |
@CallSuper | |
void removeHeaderView(View headerView) { | |
this.headerViews.remove(headerView); | |
} | |
@CallSuper | |
public void addFooterView(View footerView) { | |
this.footerViews.add(footerView); | |
} | |
@CallSuper | |
void removeFooterView(View footerView) { | |
this.footerViews.remove(footerView); | |
} | |
private boolean isListHeaderPosition(int position) { | |
return position < headerViews.size(); | |
} | |
private boolean isListFooterPosition(int position) { | |
return position >= getListItemCount() + headerViews.size(); | |
} | |
/** | |
* @param context - activity context | |
* @param headerViewType -- must be UNIQUE; used to identify a header view | |
* @param footerViewType -- must be UNIQUE; used to identify a footer view | |
*/ | |
protected BaseRecyclerViewAdapter(Context context, @IdRes int headerViewType, @IdRes int footerViewType) { | |
super(); | |
inflater = LayoutInflater.from(context); | |
this.headerViewType = headerViewType; | |
this.footerViewType = footerViewType; | |
headerViews = new ArrayList<>(); | |
footerViews = new ArrayList<>(); | |
} | |
public static class FixedViewHolder extends RecyclerView.ViewHolder { | |
public final FrameLayout frameLayout; | |
public FixedViewHolder(FrameLayout view) { | |
super(view); | |
frameLayout = view; | |
} | |
} | |
@Override | |
public final int getItemViewType(int position) { | |
if (isListHeaderPosition(position)) { | |
return headerViewType; | |
} | |
if (isListFooterPosition(position)) { | |
return footerViewType; | |
} | |
return getListItemViewType(convertAdapterPositionToUnderlyingListDataPosition(position)); | |
} | |
@Override | |
public final int getItemCount() { | |
return headerViews.size() + footerViews.size() + getListItemCount(); | |
} | |
@Override | |
public final RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int typeView) { | |
if (typeView == headerViewType || typeView == footerViewType) { | |
final FrameLayout headerContainer = (FrameLayout) inflater.inflate(R.layout.empty_container, parent, false); | |
return new FixedViewHolder(headerContainer); | |
} | |
return onCreateListItemViewHolder(parent, typeView); | |
} | |
public int convertAdapterPositionToUnderlyingListDataPosition(int position) { | |
return position - headerViews.size(); | |
} | |
int convertUnderlyingListDataPositionToAdapterPosition(int position) { | |
return position + headerViews.size(); | |
} | |
@Override | |
public final void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) { | |
if (viewHolder instanceof FixedViewHolder) { | |
if (isListHeaderPosition(position)) { | |
bindNonItemView((FixedViewHolder) viewHolder, headerViews.get(position), headerShouldSpanView); | |
return; | |
} | |
if (isListFooterPosition(position)) { | |
bindNonItemView((FixedViewHolder) viewHolder, footerViews.get(getFooterIndex(position)), footerShouldSpanView); | |
return; | |
} | |
return; | |
} | |
//noinspection unchecked | |
onBindListItemViewHolder((T) viewHolder, convertAdapterPositionToUnderlyingListDataPosition(position)); | |
} | |
private void bindNonItemView(FixedViewHolder viewHolder, View view, boolean shouldSpanView) { | |
if (viewHolder.itemView.getLayoutParams() instanceof StaggeredGridLayoutManager.LayoutParams && shouldSpanView) { | |
StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) viewHolder.itemView.getLayoutParams(); | |
layoutParams.setFullSpan(true); | |
} | |
if (viewHolder.frameLayout.getChildCount() > 0) { | |
viewHolder.frameLayout.removeAllViews(); | |
} | |
ViewGroup parent = (ViewGroup) view.getParent(); | |
if (parent != null) { | |
parent.removeView(view); | |
} | |
viewHolder.frameLayout.addView(view); | |
if (viewHolder.frameLayout.getLayoutParams() instanceof StaggeredGridLayoutManager.LayoutParams && shouldSpanView) { | |
StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) viewHolder.frameLayout.getLayoutParams(); | |
layoutParams.setFullSpan(true); | |
viewHolder.frameLayout.setLayoutParams(layoutParams); | |
} | |
} | |
private int getFooterIndex(int position) { | |
return position - getListItemCount() - headerViews.size(); | |
} | |
@Override | |
public final long getItemId(int position) { | |
if (isListHeaderPosition(position) || isListFooterPosition(position)) { | |
return -1; | |
} | |
return getListItemId(convertAdapterPositionToUnderlyingListDataPosition(position)); | |
} | |
protected abstract RecyclerView.ViewHolder onCreateListItemViewHolder(ViewGroup parent, int typeView); | |
protected abstract void onBindListItemViewHolder(T viewHolder, int position); | |
protected abstract int getListItemCount(); | |
@IdRes | |
protected abstract int getListItemViewType(int position); | |
protected abstract long getListItemId(int position); | |
public int getHeaderCount() { | |
return headerViews != null ? headerViews.size() : 0; | |
} | |
public int getFooterCount() { | |
return footerViews != null ? footerViews.size() : 0; | |
} | |
public void setHeaderShouldSpanView(boolean headerShouldSpanView) { | |
this.headerShouldSpanView = headerShouldSpanView; | |
if (headerViews.size() > 0) { | |
notifyItemRangeChanged(0, headerViews.size() - 1); | |
} | |
} | |
public void setFooterShouldSpanView(boolean footerShouldSpanView) { | |
this.footerShouldSpanView = footerShouldSpanView; | |
if (footerViews.size() > 0) { | |
notifyItemRangeChanged(getItemCount() - footerViews.size() - 1, getItemCount() - 1); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment