/*
* Copyright (c) 2015 OpenSilk Productions LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.opensilk.common.ui.recycler;
import android.support.v4.view.MotionEventCompat;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by drew on 9/5/15.
*/
public class DragSwipeAdapterWrapper<VH extends RecyclerView.ViewHolder>
extends RecyclerView.Adapter<VH> implements SimpleItemTouchHelperCallback.Listener {
public interface Listener {
void onChange();
}
protected final RecyclerListAdapter<?, VH> wrappedAdapter;
protected final Listener listener;
protected ItemTouchHelper itemTouchHelper;
public DragSwipeAdapterWrapper(RecyclerListAdapter<?, VH> wrappedAdapter, Listener listener) {
super();
this.wrappedAdapter = wrappedAdapter;
this.wrappedAdapter.registerAdapterDataObserver(observer);
this.listener = listener;
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
itemTouchHelper = new ItemTouchHelper(new SimpleItemTouchHelperCallback(this));
itemTouchHelper.attachToRecyclerView(recyclerView);
wrappedAdapter.onAttachedToRecyclerView(recyclerView);
}
@Override
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
super.onDetachedFromRecyclerView(recyclerView);
itemTouchHelper = null;
wrappedAdapter.onDetachedFromRecyclerView(recyclerView);
}
@Override
public boolean onItemMove(int fromPosition, int toPosition) {
boolean success = wrappedAdapter.move(fromPosition, toPosition);
if (success && listener != null) {
listener.onChange();
}
return success;
}
@Override
public void onItemDismiss(int position) {
Object obj = wrappedAdapter.removeItem(position);
if (obj != null && listener != null) {
listener.onChange();
}
}
@Override
public VH onCreateViewHolder(ViewGroup viewGroup, int i) {
return wrappedAdapter.onCreateViewHolder(viewGroup, i);
}
@Override
public void onBindViewHolder(final VH viewHolder, int i) {
wrappedAdapter.onBindViewHolder(viewHolder, i);
// Start a drag whenever the handle view it touched
if (viewHolder instanceof DragSwipeViewHolder) {
DragSwipeViewHolder vh = (DragSwipeViewHolder) viewHolder;
vh.getDragHandle().setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
itemTouchHelper.startDrag(viewHolder);
}
return false;
}
});
}
}
@Override
public int getItemCount() {
return wrappedAdapter.getItemCount();
}
@Override
public int getItemViewType(int position) {
return wrappedAdapter.getItemViewType(position);
}
final RecyclerView.AdapterDataObserver observer = new RecyclerView.AdapterDataObserver() {
@Override
public void onChanged() {
notifyDataSetChanged();
}
@Override
public void onItemRangeChanged(int positionStart, int itemCount) {
notifyItemRangeChanged(positionStart, itemCount);
}
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
notifyItemRangeInserted(positionStart, itemCount);
}
@Override
public void onItemRangeRemoved(int positionStart, int itemCount) {
notifyItemRangeRemoved(positionStart, itemCount);
}
@Override
public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
notifyItemMoved(fromPosition, toPosition);
}
@Override
public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
notifyItemRangeChanged(positionStart, itemCount, payload);
}
};
}