package com.pan.materialdrawer.adapter;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import com.pan.materialdrawer.model.AbstractDrawerItem;
import com.pan.materialdrawer.model.interfaces.IDrawerItem;
import com.pan.materialdrawer.model.interfaces.Selectable;
import com.pan.materialdrawer.util.RecyclerViewCacheUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
/**
* Created by mikepenz on 14.07.15.
*/
public abstract class BaseDrawerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<IDrawerItem> mHeaderDrawerItems = new ArrayList<>();
private ArrayList<IDrawerItem> mDrawerItems = new ArrayList<>();
private ArrayList<IDrawerItem> mFooterDrawerItems = new ArrayList<>();
private LinkedList<String> mTypeIds = new LinkedList<>();
private LinkedHashMap<String, IDrawerItem> mTypeInstances = new LinkedHashMap<>();
private int previousSelection = -1;
private OnClickListener mOnClickListener;
private OnLongClickListener mOnLongClickListener;
public BaseDrawerAdapter() {
}
public BaseDrawerAdapter(ArrayList<IDrawerItem> drawerItems) {
setDrawerItems(drawerItems);
}
public void setOnClickListener(OnClickListener mOnClickListener) {
this.mOnClickListener = mOnClickListener;
}
public void setOnLongClickListener(OnLongClickListener mOnLongClickListener) {
this.mOnLongClickListener = mOnLongClickListener;
}
public ArrayList<IDrawerItem> getDrawerItems() {
return mDrawerItems;
}
public void setDrawerItems(ArrayList<IDrawerItem> drawerItems) {
mDrawerItems = drawerItems;
mapPossibleTypes(drawerItems);
notifyItemRangeChanged(getHeaderItemCount(), getDrawerItemCount());
}
public void addDrawerItems(IDrawerItem... drawerItems) {
int length = mDrawerItems.size();
if (drawerItems != null) {
Collections.addAll(mDrawerItems, drawerItems);
mapPossibleTypes(mDrawerItems);
notifyItemRangeInserted(length, drawerItems.length);
}
}
public void setDrawerItem(int position, IDrawerItem drawerItem) {
mDrawerItems.set(position - getHeaderItemCount(), drawerItem);
mapPossibleType(drawerItem);
notifyItemChanged(position);
}
public void addDrawerItem(IDrawerItem drawerItem) {
mDrawerItems.add(drawerItem);
mapPossibleType(drawerItem);
notifyItemInserted(mDrawerItems.size());
}
public void addDrawerItem(int position, IDrawerItem drawerItem) {
mDrawerItems.add(position - getHeaderItemCount(), drawerItem);
mapPossibleType(drawerItem);
notifyItemInserted(position);
}
public void removeDrawerItem(int position) {
mDrawerItems.remove(position - getHeaderItemCount());
notifyItemRemoved(position);
}
public void clearDrawerItems() {
int count = mDrawerItems.size();
mDrawerItems.clear();
notifyItemRangeRemoved(getHeaderItemCount(), count);
}
public void clearHeaderItems() {
int size = mHeaderDrawerItems.size();
mHeaderDrawerItems.clear();
if (size > 0) {
notifyItemRemoved(0);
}
}
public void clearFooterItems() {
int count = mFooterDrawerItems.size();
mFooterDrawerItems.clear();
notifyItemRangeRemoved(getHeaderItemCount() + getDrawerItemCount(), count);
}
public ArrayList<IDrawerItem> getHeaderDrawerItems() {
return mHeaderDrawerItems;
}
public void setHeaderDrawerItems(ArrayList<IDrawerItem> mHeaderDrawerItems) {
this.mHeaderDrawerItems = mHeaderDrawerItems;
notifyItemRangeInserted(0, mHeaderDrawerItems.size());
mapPossibleTypes(mHeaderDrawerItems);
}
public void addHeaderDrawerItems(IDrawerItem... drawerItems) {
if (drawerItems != null) {
Collections.addAll(mHeaderDrawerItems, drawerItems);
notifyItemRangeInserted(0, drawerItems.length);
}
mapPossibleTypes(mHeaderDrawerItems);
}
public ArrayList<IDrawerItem> getFooterDrawerItems() {
return mFooterDrawerItems;
}
public void setFooterDrawerItems(ArrayList<IDrawerItem> mFooterDrawerItems) {
this.mFooterDrawerItems = mFooterDrawerItems;
notifyItemRangeInserted(0, mFooterDrawerItems.size());
mapPossibleTypes(mFooterDrawerItems);
}
public void addFooterDrawerItems(IDrawerItem... drawerItems) {
if (drawerItems != null) {
Collections.addAll(mFooterDrawerItems, drawerItems);
notifyItemRangeInserted(0, drawerItems.length);
}
mapPossibleTypes(mFooterDrawerItems);
}
/**
* internal mapper to remember and add possible types for the RecyclerView
*/
private void mapPossibleTypes(List<IDrawerItem> drawerItemList) {
if (drawerItemList != null) {
for (IDrawerItem drawerItem : drawerItemList) {
mapPossibleType(drawerItem);
}
}
}
/**
* internal mapper to remember and add possible types for the RecyclerView
*/
private void mapPossibleType(IDrawerItem drawerItem) {
if (!mTypeInstances.containsKey(drawerItem.getType())) {
mTypeIds.add(drawerItem.getType());
mTypeInstances.put(drawerItem.getType(), drawerItem);
}
}
@Override
public int getItemViewType(int position) {
return mTypeIds.indexOf(getItem(position).getType());
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//first check if we (probably) have this item in the cache
RecyclerView.ViewHolder vh = RecyclerViewCacheUtil.getInstance().obtain(mTypeIds.get(viewType));
if (vh == null) {
return mTypeInstances.get(mTypeIds.get(viewType)).getViewHolder(parent);
} else {
return vh;
}
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
getItem(position).bindView(holder);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = holder.getAdapterPosition();
IDrawerItem drawerItem = getItem(pos);
//make sure there is a DrawerItem for the specific position
if (drawerItem != null) {
//if we are enabled allow the selection and call the onClick
if (drawerItem.isEnabled()) {
if (drawerItem instanceof Selectable) {
if (drawerItem.isSelectable()) {
handleSelection(v, pos);
}
}
if (mOnClickListener != null) {
mOnClickListener.onClick(v, pos, drawerItem);
}
//if this is an abstractDrawerItem and it has an onDrawerItemClickListener call it
if (drawerItem instanceof AbstractDrawerItem) {
AbstractDrawerItem adi = (AbstractDrawerItem) drawerItem;
if (adi.getOnDrawerItemClickListener() != null) {
adi.getOnDrawerItemClickListener().onItemClick(v, pos, drawerItem);
}
}
}
}
}
});
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (mOnLongClickListener != null) {
int pos = holder.getAdapterPosition();
return mOnLongClickListener.onLongClick(v, pos, getItem(pos));
}
return false;
}
});
}
/**
* handles the selection on click and deselects previous selected items
*
* @param v
* @param pos
*/
public void handleSelection(View v, int pos) {
//deselect the previous item
if (previousSelection > -1) {
IDrawerItem prev = getItem(previousSelection);
if (prev != null) {
prev.withSetSelected(false);
}
notifyItemChanged(previousSelection);
} else {
//if there was no previous selection we have to iterate over all so we can deselect the previous item
for (int i = 0; i < getItemCount(); i++) {
if (getItem(i).isSelected()) {
getItem(i).withSetSelected(false);
notifyItemChanged(i);
break;
}
}
}
//highlight the new item
if (pos > -1) {
IDrawerItem cur = getItem(pos);
if (cur != null) {
cur.withSetSelected(true);
}
notifyItemChanged(pos);
if (v != null) {
v.setSelected(true);
v.invalidate();
}
}
previousSelection = pos;
}
public boolean isEnabled(int position) {
IDrawerItem item = getItem(position);
return item != null && item.isEnabled();
}
public boolean isSelected(int position) {
IDrawerItem item = getItem(position);
return item != null && item.isSelected();
}
public IDrawerItem getItem(int position) {
if (position < 0 || position >= getItemCount()) {
return null;
}
if (position < getHeaderItemCount()) {
return mHeaderDrawerItems.get(position);
} else if (position < (getHeaderItemCount() + getDrawerItemCount())) {
return mDrawerItems.get(position - getHeaderItemCount());
} else {
return mFooterDrawerItems.get(position - getHeaderItemCount() - getDrawerItemCount());
}
}
@Override
public long getItemId(int position) {
IDrawerItem item = getItem(position);
if (item != null && item.getIdentifier() != -1) {
return item.getIdentifier();
}
return super.getItemId(position);
}
@Override
public int getItemCount() {
int itemCount = 0;
itemCount = itemCount + getHeaderItemCount();
itemCount = itemCount + getDrawerItemCount();
itemCount = itemCount + getFooterItemCount();
return itemCount;
}
public int getHeaderOffset() {
return getHeaderItemCount();
}
protected int getHeaderItemCount() {
return mHeaderDrawerItems == null ? 0 : mHeaderDrawerItems.size();
}
protected int getDrawerItemCount() {
return mDrawerItems == null ? 0 : mDrawerItems.size();
}
protected int getFooterItemCount() {
return mFooterDrawerItems == null ? 0 : mFooterDrawerItems.size();
}
public interface OnClickListener {
void onClick(View v, int position, IDrawerItem item);
}
public interface OnLongClickListener {
boolean onLongClick(View v, int position, IDrawerItem item);
}
}