package com.github.florent37.carpaccio.controllers.adapter;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import com.github.florent37.carpaccio.Carpaccio;
import java.util.ArrayList;
import java.util.List;
/**
* Created by florentchampigny on 27/07/15.
*/
public class CarpaccioRecyclerViewAdapter<T> extends RecyclerView.Adapter<Holder> {
Carpaccio carpaccio;
int layoutResId;
String mappedName;
OnItemClickListener<T> onItemClickListener;
OnHeaderClickListener onHeaderClickListener;
RecyclerViewCallback recyclerViewCallback;
List<Integer> headerViewTypes = new ArrayList<>();
List<Header> headers = new ArrayList<>();
RecyclerView recyclerView;
OnItemSwipedListener<T> onItemSwipedListener;
ItemTouchHelper swipeItemTouch;
RecyclerView.OnItemTouchListener itemClickListener;
public CarpaccioRecyclerViewAdapter(Carpaccio carpaccio, int layoutResId, String mappedName) {
this.carpaccio = carpaccio;
this.layoutResId = layoutResId;
this.mappedName = mappedName;
carpaccio.registerAdapter(mappedName, this);
}
public CarpaccioRecyclerViewAdapter(String mappedName) {
this.mappedName = mappedName;
}
public void setCarpaccio(Carpaccio carpaccio) {
this.carpaccio = carpaccio;
}
public void setLayoutResId(int layoutResId) {
this.layoutResId = layoutResId;
}
public RecyclerViewCallback getRecyclerViewCallback() {
return recyclerViewCallback;
}
public void setRecyclerViewCallback(RecyclerViewCallback recyclerViewCallback) {
this.recyclerViewCallback = recyclerViewCallback;
}
@Override
public int getItemViewType(int position) {
int itemType = -1;
if (recyclerViewCallback != null)
itemType = recyclerViewCallback.getItemViewType(position);
if (itemType != -1)
return itemType;
else if (position < getHeaderCount()) {
int viewType = Integer.MIN_VALUE + position;
headerViewTypes.add(viewType);
return viewType;
} else
return super.getItemViewType(position);
}
@Override
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
View cellView = null;
if (recyclerViewCallback != null) {
int layoutId = recyclerViewCallback.onCreateViewHolder(viewType);
if (layoutId > 0)
cellView = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
}
if (headerViewTypes.contains(viewType)) {
int layoutId = headers.get(headerViewTypes.indexOf(viewType)).layoutId;
if (layoutId > 0)
cellView = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
}
if (cellView == null)
cellView = LayoutInflater.from(parent.getContext()).inflate(layoutResId, parent, false);
carpaccio.addChildViews(cellView);
if (recyclerViewCallback != null) { //customize holder
Holder holder = recyclerViewCallback.onCreateViewHolder(cellView, viewType);
if (holder != null)
return holder;
}
return new Holder(cellView);
}
public Object getItemForRow(View view, int position) {
if (Carpaccio.IN_EDIT_MODE) {
return new Object();
} else if (position < getHeaderCount()) {
return carpaccio.bindView(view, headers.get(position).mappedName);
} else {
return carpaccio.bindView(view, mappedName, position - getHeaderCount());
}
}
public <T> T getItem(int position) {
if (Carpaccio.IN_EDIT_MODE) {
return (T) new Object();
} else {
return (T) carpaccio.getMappedList(mappedName).get(position - getHeaderCount());
}
}
@Override
public void onBindViewHolder(final Holder holder, final int position) {
final Object mappedObject = getItemForRow(holder.itemView, position);
holder.position = position;
holder.mappedObject = mappedObject;
holder.onBind(mappedObject);
if (recyclerViewCallback != null) {
recyclerViewCallback.onBind(mappedObject, holder, position);
}
}
@Override
public int getItemCount() {
int count = getHeaderCount();
List mappedList = carpaccio.getMappedList(mappedName);
if (mappedList != null)
count += mappedList.size();
return count;
}
public int getHeaderCount() {
return headers.size();
}
public void addHeader(Header header) {
headers.add(header);
}
//region listeners
public OnItemClickListener<T> getOnItemClickListener() {
return onItemClickListener;
}
public void setOnItemClickListener(OnItemClickListener<T> onItemClickListener) {
this.onItemClickListener = onItemClickListener;
attachListeners();
}
public void setOnHeaderClickListener(OnHeaderClickListener onHeaderClickListener) {
this.onHeaderClickListener = onHeaderClickListener;
attachListeners();
}
public OnItemSwipedListener<T> getOnItemSwipedListener() {
return onItemSwipedListener;
}
public void setOnItemSwipedListener(OnItemSwipedListener<T> onItemSwipedListener) {
this.onItemSwipedListener = onItemSwipedListener;
attachListeners();
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
this.recyclerView = recyclerView;
attachListeners();
}
@Override
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
super.onDetachedFromRecyclerView(recyclerView);
this.recyclerView = null;
}
protected void attachListeners() {
if (onItemSwipedListener != null && recyclerView != null) {
if (swipeItemTouch == null) {
// init swipe to dismiss logic
swipeItemTouch = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
// callback for drag-n-drop, false to skip this feature
return false;
}
@Override
public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
if (viewHolder.getAdapterPosition() < getHeaderCount())
return 0;
else if (onItemSwipedListener != null && !onItemSwipedListener.canSwipe(viewHolder.getAdapterPosition() - getHeaderCount(), (T) getItem(viewHolder.getAdapterPosition())))
return 0;
else
return super.getSwipeDirs(recyclerView, viewHolder);
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
// callback for swipe to dismiss, removing item from data and adapter
int position = viewHolder.getAdapterPosition();
int positionLessHeader = viewHolder.getAdapterPosition() - getHeaderCount();
boolean remove = onItemSwipedListener.onItemSwiped((T) getItem(viewHolder.getAdapterPosition()), viewHolder.getAdapterPosition(), (Holder) viewHolder, CarpaccioRecyclerViewAdapter.this);
if (remove) {
carpaccio.getMappedList(mappedName).remove(positionLessHeader);
notifyItemRemoved(position);
} else
notifyItemChanged(position);
}
});
swipeItemTouch.attachToRecyclerView(recyclerView);
}
}
if (onItemClickListener != null && recyclerView != null) {
if (itemClickListener == null) {
itemClickListener = new RecyclerView.OnItemTouchListener() {
GestureDetector mGestureDetector;
@Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && onItemClickListener != null) {
int position = view.getChildAdapterPosition(childView);
if (mGestureDetector == null) {
mGestureDetector = new GestureDetector(recyclerView.getContext(), new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
});
}
if(position >= getHeaderCount()) {
T item = (T) getItem(position);
Holder holder = (Holder) view.getChildViewHolder(childView);
if (onItemClickListener.isClickable(item, position, holder))
if (mGestureDetector.onTouchEvent(e)) {
onItemClickListener.onItemClick(item, position, holder);
return true;
}
}else if(onHeaderClickListener != null){
Holder holder = (Holder) view.getChildViewHolder(childView);
onHeaderClickListener.onHeaderClick(holder.mappedObject,position,holder);
}
}
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
};
recyclerView.addOnItemTouchListener(itemClickListener);
}
}
}
//endregion
}