package net.droidlabs.mvvm.recyclerview.adapter;
import android.databinding.DataBindingUtil;
import android.databinding.ObservableArrayList;
import android.databinding.ObservableList;
import android.databinding.ViewDataBinding;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import net.droidlabs.mvvm.recyclerview.adapter.binder.ItemBinder;
import java.lang.ref.WeakReference;
import java.util.Collection;
public class BindingRecyclerViewAdapter<T> extends RecyclerView.Adapter<BindingRecyclerViewAdapter.ViewHolder> implements View.OnClickListener, View.OnLongClickListener
{
private static final int ITEM_MODEL = -124;
private final WeakReferenceOnListChangedCallback onListChangedCallback;
private final ItemBinder<T> itemBinder;
private ObservableList<T> items;
private LayoutInflater inflater;
private ClickHandler<T> clickHandler;
private LongClickHandler<T> longClickHandler;
public BindingRecyclerViewAdapter(ItemBinder<T> itemBinder, @Nullable Collection<T> items)
{
this.itemBinder = itemBinder;
this.onListChangedCallback = new WeakReferenceOnListChangedCallback<>(this);
setItems(items);
}
public ObservableList<T> getItems()
{
return items;
}
public void setItems(@Nullable Collection<T> items)
{
if (this.items == items)
{
return;
}
if (this.items != null)
{
this.items.removeOnListChangedCallback(onListChangedCallback);
notifyItemRangeRemoved(0, this.items.size());
}
if (items instanceof ObservableList)
{
this.items = (ObservableList<T>) items;
notifyItemRangeInserted(0, this.items.size());
this.items.addOnListChangedCallback(onListChangedCallback);
}
else if (items != null)
{
this.items = new ObservableArrayList<>();
this.items.addOnListChangedCallback(onListChangedCallback);
this.items.addAll(items);
}
else
{
this.items = null;
}
}
@Override
public void onDetachedFromRecyclerView(RecyclerView recyclerView)
{
if (items != null)
{
items.removeOnListChangedCallback(onListChangedCallback);
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int layoutId)
{
if (inflater == null)
{
inflater = LayoutInflater.from(viewGroup.getContext());
}
ViewDataBinding binding = DataBindingUtil.inflate(inflater, layoutId, viewGroup, false);
return new ViewHolder(binding);
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position)
{
final T item = items.get(position);
viewHolder.binding.setVariable(itemBinder.getBindingVariable(item), item);
viewHolder.binding.getRoot().setTag(ITEM_MODEL, item);
viewHolder.binding.getRoot().setOnClickListener(this);
viewHolder.binding.getRoot().setOnLongClickListener(this);
viewHolder.binding.executePendingBindings();
}
@Override
public int getItemViewType(int position)
{
return itemBinder.getLayoutRes(items.get(position));
}
@Override
public int getItemCount()
{
return items == null ? 0 : items.size();
}
@Override
public void onClick(View v)
{
if (clickHandler != null)
{
T item = (T) v.getTag(ITEM_MODEL);
clickHandler.onClick(item);
}
}
@Override
public boolean onLongClick(View v)
{
if (longClickHandler != null)
{
T item = (T) v.getTag(ITEM_MODEL);
longClickHandler.onLongClick(item);
return true;
}
return false;
}
public static class ViewHolder extends RecyclerView.ViewHolder
{
final ViewDataBinding binding;
ViewHolder(ViewDataBinding binding)
{
super(binding.getRoot());
this.binding = binding;
}
}
private static class WeakReferenceOnListChangedCallback<T> extends ObservableList.OnListChangedCallback
{
private final WeakReference<BindingRecyclerViewAdapter<T>> adapterReference;
public WeakReferenceOnListChangedCallback(BindingRecyclerViewAdapter<T> bindingRecyclerViewAdapter)
{
this.adapterReference = new WeakReference<>(bindingRecyclerViewAdapter);
}
@Override
public void onChanged(ObservableList sender)
{
RecyclerView.Adapter adapter = adapterReference.get();
if (adapter != null)
{
adapter.notifyDataSetChanged();
}
}
@Override
public void onItemRangeChanged(ObservableList sender, int positionStart, int itemCount)
{
RecyclerView.Adapter adapter = adapterReference.get();
if (adapter != null)
{
adapter.notifyItemRangeChanged(positionStart, itemCount);
}
}
@Override
public void onItemRangeInserted(ObservableList sender, int positionStart, int itemCount)
{
RecyclerView.Adapter adapter = adapterReference.get();
if (adapter != null)
{
adapter.notifyItemRangeInserted(positionStart, itemCount);
}
}
@Override
public void onItemRangeMoved(ObservableList sender, int fromPosition, int toPosition, int itemCount)
{
RecyclerView.Adapter adapter = adapterReference.get();
if (adapter != null)
{
adapter.notifyItemMoved(fromPosition, toPosition);
}
}
@Override
public void onItemRangeRemoved(ObservableList sender, int positionStart, int itemCount)
{
RecyclerView.Adapter adapter = adapterReference.get();
if (adapter != null)
{
adapter.notifyItemRangeRemoved(positionStart, itemCount);
}
}
}
public void setClickHandler(ClickHandler<T> clickHandler)
{
this.clickHandler = clickHandler;
}
public void setLongClickHandler(LongClickHandler<T> clickHandler)
{
this.longClickHandler = clickHandler;
}
}