/*
|
* Copyright (C) 2015 Paul Burke
|
*
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
* you may not use this file except in compliance with the License.
|
* You may obtain a copy of the License at
|
*
|
* http://www.apache.org/licenses/LICENSE-2.0
|
*
|
* Unless required by applicable law or agreed to in writing, software
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* See the License for the specific language governing permissions and
|
* limitations under the License.
|
*/
|
|
package com.ypx.imagepicker.helper.recyclerviewitemhelper;
|
|
import android.graphics.Canvas;
|
|
import androidx.recyclerview.widget.GridLayoutManager;
|
import androidx.recyclerview.widget.ItemTouchHelper;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.RecyclerView;
|
|
|
/**
|
* An implementation of {@link ItemTouchHelper.Callback} that enables basic drag & drop and
|
* swipe-to-dismiss. Drag events are automatically started by an item long-press.<br/>
|
* </br/>
|
* Expects the <code>RecyclerView.Adapter</code> to listen for {@link
|
* ItemTouchHelperAdapter} callbacks and the <code>RecyclerView.ViewHolder</code> to implement
|
* {@link ItemTouchHelperViewHolder}.
|
*
|
* @author Paul Burke (ipaulpro)
|
*/
|
public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
|
public static final float ALPHA_FULL = 1.0f;
|
private boolean moveFreely = false;
|
private boolean lastActive = false;
|
// 移动时,item 的放大系数
|
private float moveScaleFactor = 1.1f;
|
private final ItemTouchHelperAdapter mAdapter;
|
private OnSelectChangedListener mOnSelectChangedListener;
|
|
public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter) {
|
mAdapter = adapter;
|
}
|
|
public void setOnSelectChangedListener(OnSelectChangedListener mOnSelectChangedListener) {
|
this.mOnSelectChangedListener = mOnSelectChangedListener;
|
}
|
|
public void setMoveScaleFactor(float moveScaleFactor) {
|
this.moveScaleFactor = moveScaleFactor;
|
}
|
|
@Override
|
public boolean isItemViewSwipeEnabled() {
|
return mAdapter.isItemViewSwipeEnabled();
|
}
|
|
public interface OnSelectChangedListener {
|
/**
|
* @param viewHolder
|
* @param dX
|
* @param dY
|
* @param actionState
|
* @param isCurrentlyActive
|
*/
|
void onSelectedChanged(RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive);
|
|
/**
|
* @param viewHolder
|
* @param actionState
|
*/
|
void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState);
|
}
|
|
@Override
|
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
|
// Set movement flags based on the layout manager
|
if (moveFreely) {
|
final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
|
final int swipeFlags = ItemTouchHelper.ACTION_STATE_IDLE;
|
return makeMovementFlags(dragFlags, swipeFlags);
|
} else if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
|
final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
|
final int swipeFlags = 0;
|
return makeMovementFlags(dragFlags, swipeFlags);
|
} else if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) {
|
LinearLayoutManager linear = (LinearLayoutManager) recyclerView.getLayoutManager();
|
if (linear.getOrientation() == RecyclerView.HORIZONTAL) {
|
final int dragFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
|
final int swipeFlags = ItemTouchHelper.ACTION_STATE_IDLE;
|
return makeMovementFlags(dragFlags, swipeFlags);
|
} else {
|
final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
|
final int swipeFlags = ItemTouchHelper.ACTION_STATE_IDLE;
|
return makeMovementFlags(dragFlags, swipeFlags);
|
}
|
} else {
|
final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
|
final int swipeFlags = ItemTouchHelper.ACTION_STATE_IDLE;
|
return makeMovementFlags(dragFlags, swipeFlags);
|
}
|
}
|
|
@Override
|
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
|
if (source.getItemViewType() != target.getItemViewType()) {
|
return false;
|
}
|
|
// Notify the adapter of the move
|
mAdapter.onItemMove(source.getAdapterPosition(), target.getAdapterPosition());
|
return true;
|
}
|
|
@Override
|
public void onMoved(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, int fromPos, RecyclerView.ViewHolder target, int toPos, int x, int y) {
|
super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y);
|
viewHolder.itemView.setAlpha(1f);
|
target.itemView.setAlpha(1f);
|
}
|
|
@Override
|
public void onSwiped(RecyclerView.ViewHolder viewHolder, int i) {
|
// Notify the adapter of the dismissal
|
mAdapter.onItemDismiss(viewHolder.getAdapterPosition());
|
}
|
|
@Override
|
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
|
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
|
// Fade out the view as it is swiped out of the parent's bounds
|
final float alpha = ALPHA_FULL - Math.abs(dX) / (float) viewHolder.itemView.getWidth();
|
viewHolder.itemView.setAlpha(alpha);
|
viewHolder.itemView.setTranslationX(dX);
|
} else if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) {
|
if (isCurrentlyActive) {
|
viewHolder.itemView.setAlpha(0.5f);
|
viewHolder.itemView.setScaleX(moveScaleFactor);
|
viewHolder.itemView.setScaleY(moveScaleFactor);
|
} else {
|
viewHolder.itemView.setAlpha(1f);
|
viewHolder.itemView.setScaleX(1f);
|
viewHolder.itemView.setScaleY(1f);
|
}
|
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
|
} else {
|
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
|
}
|
|
// 从拖动到释放的过程
|
if (null != mOnSelectChangedListener && !isCurrentlyActive && lastActive) {
|
mOnSelectChangedListener.onSelectedChanged(viewHolder, dX, dY, actionState, isCurrentlyActive);
|
}
|
lastActive = isCurrentlyActive;
|
}
|
|
@Override
|
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
|
// We only want the active item to change
|
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
|
if (viewHolder instanceof ItemTouchHelperViewHolder) {
|
// Let the view holder know that this item is being moved or dragged
|
ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
|
itemViewHolder.onItemSelected();
|
}
|
}
|
super.onSelectedChanged(viewHolder, actionState);
|
|
if (null != mOnSelectChangedListener) {
|
mOnSelectChangedListener.onSelectedChanged(viewHolder, actionState);
|
}
|
}
|
|
@Override
|
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
|
super.clearView(recyclerView, viewHolder);
|
viewHolder.itemView.setAlpha(ALPHA_FULL);
|
if (viewHolder instanceof ItemTouchHelperViewHolder) {
|
// Tell the view holder it's time to restore the idle state
|
ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
|
itemViewHolder.onItemClear();
|
}
|
}
|
|
public void setMoveFreely(boolean moveFreely) {
|
this.moveFreely = moveFreely;
|
}
|
}
|