Last active
May 27, 2016 09:55
-
-
Save Rexee/733e617849255d7d5e43942755e74e31 to your computer and use it in GitHub Desktop.
RecyclerView + RecyclerView.Adapter in one class
This file contains 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
public class Recycler<T, VH extends RecyclerViewHolder> { | |
public RecyclerView mRecyclerView; | |
public RecyclerAdapter<T, VH> mAdapter; | |
public LinearLayoutManager mLinearLayoutManager; | |
public Recycler(RecyclerView recyclerView, int layoutItemResId, RecyclerAdapter<T, VH> adapter, boolean divider, boolean vertical) { | |
mRecyclerView = recyclerView; | |
Context context = mRecyclerView.getContext(); | |
if (vertical) { | |
mLinearLayoutManager = new LinearLayoutManager(context); | |
} else { | |
mLinearLayoutManager = new LinearLayoutManager(context, OrientationHelper.HORIZONTAL, false); | |
} | |
mRecyclerView.setLayoutManager(mLinearLayoutManager); | |
if (divider) mRecyclerView.addItemDecoration(new DividerItemDecoration(context)); | |
mAdapter = adapter; | |
mAdapter.setLayoutItemResId(layoutItemResId); | |
mRecyclerView.setAdapter(mAdapter); | |
} | |
public Recycler(RecyclerView recyclerView, int layoutItemResId, RecyclerAdapter<T, VH> adapter) { | |
this(recyclerView, layoutItemResId, adapter, true, true); | |
} | |
public Recycler(RecyclerView recyclerView, int layoutItemResId, RecyclerAdapter<T, VH> adapter, boolean divider) { | |
this(recyclerView, layoutItemResId, adapter, divider, true); | |
} | |
public void updateList(LinkedHashMap<String, T> newItems) { | |
mAdapter.updateList(newItems); | |
} | |
public void updateList(List<T> newItems) { | |
mAdapter.updateList(newItems); | |
} | |
public void appendList(List<T> newItems, boolean addToTop) { | |
mAdapter.appendList(newItems, addToTop); | |
} | |
public void deleteItems(boolean notify) { | |
mAdapter.deleteItems(notify); | |
} | |
public void insertList(List<T> newItems, int pos) { | |
mAdapter.insertList(newItems, pos); | |
} | |
public boolean isEmpty() { | |
return mAdapter.isEmpty(); | |
} | |
public void release() { | |
mRecyclerView.setAdapter(null); | |
mAdapter = null; | |
mRecyclerView = null; | |
mLinearLayoutManager = null; | |
} | |
public static abstract class RecyclerAdapter<T, VH extends RecyclerViewHolder> extends RecyclerView.Adapter<VH> { | |
protected List<T> mItems; | |
protected int mLayoutItemResId; | |
public void setLayoutItemResId(int layoutItemId) { | |
this.mLayoutItemResId = layoutItemId; | |
} | |
public abstract VH onCreateViewHolder(View v, int viewType); | |
public abstract void onBindViewHolder(VH holder, int position, T item); | |
@Override | |
public VH onCreateViewHolder(ViewGroup viewGroup, int viewType) { | |
View v = LayoutInflater.from(viewGroup.getContext()).inflate(mLayoutItemResId, viewGroup, false); | |
return onCreateViewHolder(v, viewType); | |
} | |
@Override | |
public void onBindViewHolder(VH holder, int position) { | |
T item = mItems.get(position); | |
onBindViewHolder(holder, position, item); | |
} | |
@Override | |
public int getItemCount() { | |
return mItems == null ? 0 : mItems.size(); | |
} | |
public int getItemPosition(T item) { | |
return mItems.indexOf(item); | |
} | |
public void updateList(List<T> items) { | |
mItems = items; | |
notifyDataSetChanged(); | |
} | |
public void updateList(LinkedHashMap<String, T> items) { | |
mItems = new ArrayList<>(items.size()); | |
mItems.addAll(items.values()); | |
notifyDataSetChanged(); | |
} | |
public void appendList(List<T> items, boolean addToTop) { | |
if (mItems == null) { | |
mItems = items; | |
notifyDataSetChanged(); | |
} else { | |
if (addToTop) { | |
mItems.addAll(0, items); | |
notifyItemRangeInserted(0, items.size()); | |
} else { | |
int pos = mItems.size(); | |
mItems.addAll(items); | |
notifyItemRangeInserted(pos, items.size()); | |
} | |
} | |
} | |
public void deleteItems(boolean notify) { | |
int count = mItems.size(); | |
mItems.clear(); | |
if (notify) notifyItemRangeRemoved(0, count); | |
} | |
public void insertList(List<T> items, int pos) { | |
if (mItems == null) { | |
mItems = items; | |
notifyDataSetChanged(); | |
} else { | |
mItems.addAll(pos, items); | |
notifyItemRangeInserted(pos, items.size()); | |
} | |
} | |
public boolean isEmpty() { | |
return mItems == null || mItems.isEmpty(); | |
} | |
public List<T> getItems() { | |
return mItems; | |
} | |
} | |
public static class RecyclerViewHolder extends RecyclerView.ViewHolder { | |
public RecyclerViewHolder(View itemView) { | |
super(itemView); | |
ButterKnife.bind(this, itemView); | |
} | |
} | |
public static class DividerItemDecoration extends RecyclerView.ItemDecoration { | |
private Drawable mDivider; | |
public boolean mShowFirstDivider = false; | |
public boolean mShowLastDivider = false; | |
public int mOrientation = -1; | |
public DividerItemDecoration(Context context, int resId) { | |
mDivider = ContextCompat.getDrawable(context, resId); | |
} | |
public DividerItemDecoration(Drawable divider) { | |
mDivider = divider; | |
} | |
public DividerItemDecoration(Context context) { | |
final TypedArray a = context.obtainStyledAttributes(new int[]{android.R.attr.listDivider}); | |
mDivider = a.getDrawable(0); | |
a.recycle(); | |
} | |
@Override | |
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { | |
super.getItemOffsets(outRect, view, parent, state); | |
if (mDivider == null) { | |
return; | |
} | |
int position = parent.getChildAdapterPosition(view); | |
if (position == RecyclerView.NO_POSITION || (position == 0 && !mShowFirstDivider)) { | |
return; | |
} | |
if (mOrientation == -1) getOrientation(parent); | |
if (mOrientation == LinearLayoutManager.VERTICAL) { | |
outRect.top = mDivider.getIntrinsicHeight(); | |
if (mShowLastDivider && position == (state.getItemCount() - 1)) { | |
outRect.bottom = outRect.top; | |
} | |
} else { | |
outRect.left = mDivider.getIntrinsicWidth(); | |
if (mShowLastDivider && position == (state.getItemCount() - 1)) { | |
outRect.right = outRect.left; | |
} | |
} | |
} | |
@Override | |
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { | |
if (mDivider == null) { | |
super.onDrawOver(c, parent, state); | |
return; | |
} | |
int left = 0, right = 0, top = 0, bottom = 0, size; | |
int orientation = mOrientation != -1 ? mOrientation : getOrientation(parent); | |
int childCount = parent.getChildCount(); | |
if (orientation == LinearLayoutManager.VERTICAL) { | |
size = mDivider.getIntrinsicHeight(); | |
left = parent.getPaddingLeft(); | |
right = parent.getWidth() - parent.getPaddingRight(); | |
} else { | |
size = mDivider.getIntrinsicWidth(); | |
top = parent.getPaddingTop(); | |
bottom = parent.getHeight() - parent.getPaddingBottom(); | |
} | |
for (int i = mShowFirstDivider ? 0 : 1; i < childCount; i++) { | |
View child = parent.getChildAt(i); | |
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); | |
if (orientation == LinearLayoutManager.VERTICAL) { | |
top = child.getTop() - params.topMargin - size; | |
bottom = top + size; | |
} else { | |
left = child.getLeft() - params.leftMargin; | |
right = left + size; | |
} | |
mDivider.setBounds(left, top, right, bottom); | |
mDivider.draw(c); | |
} | |
if (mShowLastDivider && childCount > 0) { | |
View child = parent.getChildAt(childCount - 1); | |
if (parent.getChildAdapterPosition(child) == (state.getItemCount() - 1)) { | |
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); | |
if (orientation == LinearLayoutManager.VERTICAL) { | |
top = child.getBottom() + params.bottomMargin; | |
bottom = top + size; | |
} else { | |
left = child.getRight() + params.rightMargin; | |
right = left + size; | |
} | |
mDivider.setBounds(left, top, right, bottom); | |
mDivider.draw(c); | |
} | |
} | |
} | |
private int getOrientation(RecyclerView parent) { | |
if (mOrientation == -1) { | |
if (parent.getLayoutManager() instanceof LinearLayoutManager) { | |
LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager(); | |
mOrientation = layoutManager.getOrientation(); | |
} else { | |
throw new IllegalStateException("DividerItemDecoration can only be used with a LinearLayoutManager."); | |
} | |
} | |
return mOrientation; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How to use: