先上效果图
![](https://gitee.com/zqunyan/ImgRepository/raw/master/img/0006.gif)
概述
RecyclerView 的显示实现这里就不说了,之前的文章有提到
Android中RecyclerView的简单实现
这里主要说下怎么实现这个拖动排序的功能
主要代码都在是 activity 里面实现
先初使化几个变量
这些变量主要是用来更新数据列表的,显示有简单的实现方法,但往往会出错,这里使用的方法虽然原始了一些,但可以保证 position 位置不会出错
private Boolean isFirstMove = true;
private int frmPosition = 0;
绑定拖动事件
这个比较简单,这也是RecyclerView的强大之处,只要实例化一个ItemTouchHelper,然后处理他的回调事件,就是拖动时的事件就可以了,不用再自己去计算坐标之类的
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
itemTouchHelper.attachToRecyclerView(mView.rvDesktopAppsort);
自定义实现拖动事件
ItemTouchHelper.Callback callback = new ItemTouchHelper.Callback() {
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
int swipFlag = 0; //滑动方向,这个主要是用来侧滑删除之类的操作,我这里用不到,就不实现了
//这里的拖动方向可能根据自己的需要进行调整,如果是列表类的,那只要上下拖动就要以,因为我这里是gridview样式的,所以还会用到左右拖动
int dragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; //拖动方向
return makeMovementFlags(dragFlag, swipFlag);
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
//这里只所以要记录下第一次滑动的位置,是因为滑动过程中会反复调用这个方法,导致得到的position一直在变,我这里只需要拖动项目的index和目标index就够了
if (isFirstMove) {
frmPosition = viewHolder.getAdapterPosition();
isFirstMove = false;
}
//正常只要有下面这一句就可以看到拖动效果了,但后面列表的position会乱掉,所以处理起来就要稍稍变更一下了
sortAdapter.notifyItemMoved(viewHolder.getAdapterPosition(), target.getAdapterPosition());
//以下记得把列表也要更新。但使用此方法会有一个问题就是move方法会被反复调用导致无法正常更新列表
//通过clearView的最后获取目标位置来进行更换
//Collections.swap(lstApps, viewHolder.getAdapterPosition(), target.getAdapterPosition());
return true;
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
//这个主要是用来侧滑删除之类的操作,我这里用不到,就不实现了
}
//拖动完成之后调用,所操作的viewHolder即为目标位置的项目
//为了得到目标项目的index 也要实现这个方法
@Override
public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
int endPosition = viewHolder.getAdapterPosition();
listSwap(lstApps, frmPosition, endPosition);
isFirstMove = true;
}
};
//更新列表
//本来打算使用swap的,但是这个拖动会让目标位置之间的元素全部发生位置变化,所以使用列表的移除和添加功能进行更新列表
private void listSwap(ArrayList<AppPackage> lstApp, int frm, int to){
AppPackage appPackage = lstApp.get(frm);
lstApp.remove(appPackage);
lstApp.add(to, appPackage);
}