package com.netease.nim.uikit.common.ui.recyclerview.callback;
import android.graphics.Canvas;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.View;
import com.netease.nim.uikit.R;
import com.netease.nim.uikit.common.ui.recyclerview.adapter.BaseItemDraggableAdapter;
public class ItemDragAndSwipeCallback extends ItemTouchHelper.Callback {
// private static final String TAG = ItemDragAndSwipeCallback.class.getSimpleName();
BaseItemDraggableAdapter mAdapter;
float mMoveThreshold = 0.1f;
float mSwipeThreshold = 0.7f;
int mDragMoveFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
int mSwipeMoveFlags = ItemTouchHelper.END;
public ItemDragAndSwipeCallback(BaseItemDraggableAdapter adapter) {
mAdapter = adapter;
}
@Override
public boolean isLongPressDragEnabled() {
return false;
}
@Override
public boolean isItemViewSwipeEnabled() {
return mAdapter.isItemSwipeEnable();
}
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if (actionState == ItemTouchHelper.ACTION_STATE_DRAG
&& !isViewCreateByAdapter(viewHolder)) {
mAdapter.onItemDragStart(viewHolder);
viewHolder.itemView.setTag(R.id.BaseQuickAdapter_dragging_support, true);
} else if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE
&& !isViewCreateByAdapter(viewHolder)) {
mAdapter.onItemSwipeStart(viewHolder);
viewHolder.itemView.setTag(R.id.BaseQuickAdapter_swiping_support, true);
}
super.onSelectedChanged(viewHolder, actionState);
}
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
if (isViewCreateByAdapter(viewHolder)) {
return;
}
if (viewHolder.itemView.getTag(R.id.BaseQuickAdapter_dragging_support) != null
&& (Boolean) viewHolder.itemView.getTag(R.id.BaseQuickAdapter_dragging_support)) {
mAdapter.onItemDragEnd(viewHolder);
viewHolder.itemView.setTag(R.id.BaseQuickAdapter_dragging_support, false);
}
if (viewHolder.itemView.getTag(R.id.BaseQuickAdapter_swiping_support) != null
&& (Boolean) viewHolder.itemView.getTag(R.id.BaseQuickAdapter_swiping_support)) {
mAdapter.onItemSwipeClear(viewHolder);
viewHolder.itemView.setTag(R.id.BaseQuickAdapter_swiping_support, false);
}
}
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
if (isViewCreateByAdapter(viewHolder)) {
return makeMovementFlags(0, 0);
}
return makeMovementFlags(mDragMoveFlags, mSwipeMoveFlags);
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
if (source.getItemViewType() != target.getItemViewType()) {
return false;
} else {
return true;
}
}
@Override
public void onMoved(RecyclerView recyclerView, RecyclerView.ViewHolder source, int fromPos, RecyclerView.ViewHolder target, int toPos, int x, int y) {
mAdapter.onItemDragMoving(source, target);
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
if (!isViewCreateByAdapter(viewHolder)) {
mAdapter.onItemSwiped(viewHolder);
}
}
@Override
public float getMoveThreshold(RecyclerView.ViewHolder viewHolder) {
return mMoveThreshold;
}
@Override
public float getSwipeThreshold(RecyclerView.ViewHolder viewHolder) {
return mSwipeThreshold;
}
/**
* Set the fraction that the user should move the View to be considered as swiped.
* The fraction is calculated with respect to RecyclerView's bounds.
* <p>
* Default value is .5f, which means, to swipe a View, user must move the View at least
* half of RecyclerView's width or height, depending on the swipe direction.
*
* @param swipeThreshold A float value that denotes the fraction of the View size. Default value
* is .8f .
*/
public void setSwipeThreshold(float swipeThreshold) {
mSwipeThreshold = swipeThreshold;
}
/**
* Set the fraction that the user should move the View to be considered as it is
* dragged. After a view is moved this amount, ItemTouchHelper starts checking for Views
* below it for a possible drop.
*
* @param moveThreshold A float value that denotes the fraction of the View size. Default value is
* .1f .
*/
public void setMoveThreshold(float moveThreshold) {
mMoveThreshold = moveThreshold;
}
/**
* <p>Set the drag movement direction.</p>
* <p>The value should be ItemTouchHelper.UP, ItemTouchHelper.DOWN, ItemTouchHelper.LEFT, ItemTouchHelper.RIGHT or their combination.</p>
* You can combine them like ItemTouchHelper.UP | ItemTouchHelper.DOWN, it means that the item could only move up and down when dragged.
*
* @param dragMoveFlags the drag movement direction. Default value is ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT.
*/
public void setDragMoveFlags(int dragMoveFlags) {
mDragMoveFlags = dragMoveFlags;
}
/**
* <p>Set the swipe movement direction.</p>
* <p>The value should be ItemTouchHelper.START, ItemTouchHelper.END or their combination.</p>
* You can combine them like ItemTouchHelper.START | ItemTouchHelper.END, it means that the item could swipe to both left or right.
*
* @param swipeMoveFlags the swipe movement direction. Default value is ItemTouchHelper.END.
*/
public void setSwipeMoveFlags(int swipeMoveFlags) {
mSwipeMoveFlags = swipeMoveFlags;
}
@Override
public void onChildDrawOver(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
float dX, float dY, int actionState, boolean isCurrentlyActive) {
super.onChildDrawOver(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE
&& !isViewCreateByAdapter(viewHolder)) {
View itemView = viewHolder.itemView;
c.save();
if (dX > 0) {
c.clipRect(itemView.getLeft(), itemView.getTop(),
itemView.getLeft() + dX, itemView.getBottom());
c.translate(itemView.getLeft(), itemView.getTop());
} else {
c.clipRect(itemView.getRight() + dX, itemView.getTop(),
itemView.getRight(), itemView.getBottom());
c.translate(itemView.getRight() + dX, itemView.getTop());
}
mAdapter.onItemSwiping(c, viewHolder, dX, dY, isCurrentlyActive);
c.restore();
}
}
private boolean isViewCreateByAdapter(RecyclerView.ViewHolder viewHolder) {
int type = viewHolder.getItemViewType();
if (type == mAdapter.HEADER_VIEW || type == mAdapter.LOADING_VIEW
|| type == mAdapter.FOOTER_VIEW || type == mAdapter.EMPTY_VIEW) {
return true;
}
return false;
}
}