我正在使用recyclerview和网格布局管理器。 Recyclerview项目需要在某些基础上进行分组。因为分组,每一行可以有不同的列数。
例如 - row1总共可以有4个项目,第2行只能有1个项目,依此类推。
现在我想实现拖放功能。 任何物品都可以拖到任何地方,也可以用其他物品替换,也可以将它拖到某些物品的左侧或右侧,或者拖到两个物品之间。
因此,拖放后,有4个项目的第1行现在可能有5个项目。
但是我可以实现的是将它们相互替换,而不是在视图之间。
我尝试过的代码:
public class ItemTouchHelperCallback extends ItemTouchHelper.Callback {
private final ItemTouchHelperAdapter mAdapter;
public ItemTouchHelperCallback(ItemTouchHelperAdapter adapter) {
mAdapter = adapter;
}
@Override
public boolean isLongPressDragEnabled() {
return true;
}
@Override
public boolean isItemViewSwipeEnabled() {
return false;
}
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
// Set movement flags based on the layout manager
final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
final int swipeFlags = 0;
return makeMovementFlags(dragFlags, swipeFlags);
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
// Notify the adapter of the move
mAdapter.onItemMove(source.getAdapterPosition(), target.getAdapterPosition());
return true;
}
When a dragging View overlaps multiple other views, Callback chooses the closest View with which dragged View might have changed positions. Although this approach works for many use cases, if you have a custom LayoutManager, you can override `chooseDropTarget(ViewHolder, java.util.List, int, int)` to select a custom drop target.
// Return true if the current ViewHolder can be dropped over the the target ViewHolder.
@Override
public boolean canDropOver(RecyclerView recyclerView, RecyclerView.ViewHolder current, RecyclerView.ViewHolder target) {
return super.canDropOver(recyclerView, current, target);
}
@Override
public RecyclerView.ViewHolder chooseDropTarget(RecyclerView.ViewHolder selected, List<RecyclerView.ViewHolder> dropTargets, int curX, int curY) {
return super.chooseDropTarget(selected, dropTargets, curX, curY);
}
@Override
public int convertToAbsoluteDirection(int flags, int layoutDirection) {
Log.i("flags",""+flags + " "+ ""+layoutDirection);
return super.convertToAbsoluteDirection(flags, layoutDirection);
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
// Notify the adapter of the dismissal
Log.i("onSwiped","method");
int position = viewHolder.getAdapterPosition();
if (direction == ItemTouchHelper.LEFT){
Log.i("direction","left");
// adapter.removeItem(position);
} if(direction == ItemTouchHelper.RIGHT){
Log.i("direction","right");
} if(direction == ItemTouchHelper.UP){
Log.i("direction","up");
} if(direction == ItemTouchHelper.DOWN){
Log.i("direction","down");
}
}
@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);
}
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
if (viewHolder instanceof ItemTouchHelperViewHolder) {
// Let the view holder know that this item is being moved or dragged
ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
itemViewHolder.onItemReleased();
}
mAdapter.onClearView();
}
@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) {
float width = (float) viewHolder.itemView.getWidth();
float alpha = 1.0f - Math.abs(dX) / width;
viewHolder.itemView.setAlpha(alpha);
viewHolder.itemView.setTranslationX(dX);
} else {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY,
actionState, isCurrentlyActive);
}
}
}
并在适配器中:
public boolean onItemMove(int fromPos, int toPos) {
fromPosition = fromPos - 1;
toPosition = toPos - 1;
return true;
}
@Override
public void onClearView() {
if (fromPosition != toPosition) {
//some code
}
notifyDataSetChanged();
}