RecyclerView的滑动删除和拖动排序以及排序后的position错位问题
定义相关接口:
public interface OnItemTouchListener {
boolean onMove(int fromPosition,int toPosition);
void onSwiped(int position);
}
实现接口:
public class MyItemTouchHelper extends ItemTouchHelper.Callback{
private OnItemTouchListener mListener;
private boolean sort = false;
public MyItemTouchHelper(OnItemTouchListener listener){
this.mListener = listener;
}
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
final int swipeFlags = ItemTouchHelper.START;//代表左滑删除
final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
//其实只有UP、DOWN即可完成排序,加上LEFT、RIGHT只是为了滑动更飘逸
return makeMovementFlags(dragFlags,swipeFlags);
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
int fromPosition = viewHolder.getAdapterPosition();
int toPosition = target.getAdapterPosition();
return mListener.onMove(fromPosition, toPosition);
}
/**
* 滑动删除
* @return
*/
@Override
public boolean isItemViewSwipeEnabled() {
return false;
}
public void setSort(boolean sort) {
this.sort = sort;
}
/**
* 长按 拖拽
* @return
*/
@Override
public boolean isLongPressDragEnabled() {
return sort;//true 开启拖动排序,false关闭拖动排序
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
mListener.onSwiped(viewHolder.getAdapterPosition());
}
}
使用:
MyItemTouchHelper touchHelper = new MyItemTouchHelper(this);
touchHelper.setSort(false);//默认关闭拖动排序
new ItemTouchHelper(touchHelper).attachToRecyclerView(recyclerView);
- RecyclerView的滑动删除
@Override
public void onSwiped(int position) {
//删除list中的item,然后notifyDataSetChanged,完成删除操作。
list.remove(position);
adapter.notifyDataSetChanged();
}
- RecyclerView的拖动排序
@Override
public boolean onMove(int fromPosition, int toPosition) {
if (fromPosition < toPosition) {
//从上往下拖动,每滑动一个item,都将list中的item向下交换,向上滑同理。
for (int i = fromPosition; i < toPosition; i++) {
Collections.swap(tips, i, i + 1);
}
} else {
for (int i = fromPosition; i > toPosition; i--) {
Collections.swap(tips, i, i - 1);
}
}
adapter.notifyItemMoved(fromPosition, toPosition);
//注意此处只是notifyItemMoved并没有notifyDataSetChanged
//原因下面会说明
return true;
}
- RecyclerView排序后的错位问题
此处解释之前为何使用notifyItemMoved,而不是用notifyDataSetChanged:
当使用notifyDataSetChanged每拖动一个子项目都会notify而结束拖动,就是每次只能交换一个,所以使用notifyItemMoved想怎么拖动就怎么拖动,当然notifyItemMove只是交换位置,每个位置对应的position也同时交换。
比如说:将position = 0 与position = 3 交换,此时点击第一个item 常理说 position应该是0,毕竟看到的已经交换位置了,debug发现其实只是看到的交换了,点击第一个position还是3,那么这样只是表面的交换,如果只是浏览没有操作,当然没问题,但是有点击操作就会造成position的错位,解决方案如下:
#######设置一个按钮“编辑”,点击编辑setSort(true)
开始排序,并出现“完成”按钮等待操作完成使用,此时应当屏蔽RecyclerView的其他点击点击操作,当排序完成后,点击“完成”,adapter.notifyDataSetChanged()
,这样就解决了排序后的position错位问题。
网友评论