首先,说一下需求,如下图所示一个recyclerView的网格布局,就是拖拽4与1交换位置,上来感觉这还不简单,毕竟万能适配器BaseRecyclerViewAdapterHelper开源库有现成得拖拽的方法,直接用就好了。
用完之后发现,并没有交换位置而是进行了排序,不想改变得位置也发生了变化,变成了如下所示:
显然这不符合我的需求,首先我就想的去开源库Issues中去搜,发现有兄台遇到了和我一样得需求,但是无奈截至我写这篇文章,一直没有没解决,虽然有回答但是都不符合需求。
之后又疯狂得搜有没有现成得轮子供参考,无奈没有找到合适得方法,搜了一些相关ItemTouchHelper得资料,本着能用的原则哈哈哈,改了一下,实践后可用。
java
public interface ItemDragTouchHelper {
/**
* 状态清除
* @param
* @param
*/
void onItemClear(int formPosition,int toPosition);
}
less
public class ItemDragTouchHelperCallback extends ItemTouchHelper.Callback {
private static final String TAG = "ItemDragTouchHelperCall";
private ItemDragTouchHelper helper;
private int fromPosition, toPosition;
private boolean isFirstFromMove = true;
public ItemDragTouchHelperCallback(ItemDragTouchHelper helper) {
this.helper = helper;
}
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
if( SPUtils.getInstance().getBoolean("isDrag",false)){
// 上下左右都可以拖拽
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
return makeMovementFlags(dragFlags, 0);
}else {
return makeMovementFlags(0, 0);
}
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
Log.d(TAG, "onMove: " + viewHolder.getAdapterPosition() + ";" + target.getAdapterPosition());
if (isFirstFromMove) {
fromPosition = viewHolder.getAdapterPosition();
isFirstFromMove = false;
}
toPosition = target.getAdapterPosition();
return false;
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
}
@Override
public boolean isLongPressDragEnabled() {
return true;
}
@Override
public boolean isItemViewSwipeEnabled() {
return false;
}
/**
* 当用户与元素的交互结束时
* @param recyclerView The RecyclerView which is controlled by the ItemTouchHelper.
* @param viewHolder The View that was interacted by the user.
*/
@Override
public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
if (!isFirstFromMove) {
Log.d(TAG, "clearView: " + toPosition);
if (!recyclerView.isComputingLayout()) {
helper.onItemClear(fromPosition, toPosition);
isFirstFromMove = true;
}
}
}
@Override
public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState) {
super.onSelectedChanged(viewHolder, actionState);
}
}
adapter需要实现ItemDragTouchHelper后,然后覆写onItemClear
方法中,拿到交换前,交换后得下标,然后把对应得item得数据交换,之后调用集合得swap,最后刷新适配器。
arduino
@Override
public void onItemClear(int fromPosition, int toPosition) {
Log.d("移动完成", "onItemClear: " + fromPosition + "," + toPosition);
//处理2个数据实体得交换逻辑,代码省略
//进行交换
Collections.swap(data, fromPosition, toPosition);
//刷新适配器,当然这里也可以只刷新交换前后得2个postion
notifyDataSetChanged();
}