先看效果图
demo下载 项目架构为TheMVP
- 使用ItemTouchHelper 必须自己实现 ItemTouchHelper.Callback 类
public class ItemDragHelperCallback extends ItemTouchHelper.Callback{
- 实现ItemTouchHelper.Callback类中接口方法getMovementFlags()确定方向
/**
* 指定需要拖拽的方向
*
* @param recyclerView
* @param viewHolder
* @return
*/
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
int dragFlags;//拖拽方向
int swipeFlags;//滑动方向
//针对第一个不能拖拽
if (viewHolder.getAdapterPosition() == 0) {
return 0;
}
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if (layoutManager instanceof GridLayoutManager || layoutManager instanceof StaggeredGridLayoutManager) {
dragFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT | ItemTouchHelper.UP | ItemTouchHelper.DOWN;
} else {
dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
}
swipeFlags = 0;
return makeMovementFlags(dragFlags, swipeFlags);
}
- 实现ItemTouchHelper.Callback的onMove()和onSwiped()方法
//拖拽功能在这里实现
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
//不同类型的item 不能拖拽
if (viewHolder.getItemViewType() != target.getItemViewType()) {
return false;
}
//如果目标点为第一个 也不能拖拽过去
if(target.getAdapterPosition()==0){
return false;
}
if (recyclerView.getAdapter() instanceof OnItemMoveListener) {
//这里定义一个借口有Adapter实现 然后针对数据的变动交由Adapter去具体实现
OnItemMoveListener listener = (OnItemMoveListener) recyclerView.getAdapter();
listener.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
}
return false;
}
/**
*滑动删除的方法在这里实现(本demo没有该功能)
*/
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {}
- 对应的Adapter接口
public interface OnItemMoveListener {
void onItemMove(int fromPosition, int toPosition);//item拖拽的起始位置
void onItemDismiss(int position);//滑动删除的item
}
public class NewsLabelAdapter extends RecyclerView.Adapter<NewsLabelAdapter.ViewHolder> implements OnItemMoveListener {
/**
* 拖拽交换
*
* @param fromPosition
* @param toPosition
* @return
*/
@Override
public void onItemMove(int fromPosition, int toPosition) {
Collections.swap(labels, fromPosition, toPosition);
notifyItemMoved(fromPosition, toPosition);
}
/**
* 滑动删除
*
* @param position
*/
@Override
public void onItemDismiss(int position) {
}
}
- ItemTouchHelper.CallbackisItemViewSwipeEnabled()isLongPressDragEnabled() 所对应的功能为滑动 和拖拽 根据需求是否开启
@Override
public boolean isItemViewSwipeEnabled() {
// 不需要滑动功能
return false;
}
@Override
public boolean isLongPressDragEnabled() {
// 长按拖拽功能
return true;
}
- 最后 我们可以创建自己的ItemTouchHelper实例并调用attachToRecyclerView(RecyclerView)方法 就能实现该功能了
ItemDragHelperCallback callback=new ItemDragHelperCallback();
ItemTouchHelper helper=new ItemTouchHelper(callback);
itemHelper.attachToRecyclerView(top_recyclerView);
- 开过程中遇到的坑
- RecyclerView的item只能显示一列由参数parent造成 在inflate(R.layout.item_label, null, false)中第二个参数不能传parent 换为null就好了
//在inflate(R.layout.item_label, null, false)中第二个参数不能传parent 换为null就好了
@Override
public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_label, null, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
- 在添加或者删除item数据时 造成集合数据position混乱是由 notifyItemRemoved(position);造成的 在后面再调用notifyItemRangeChanged(0,labels.size());就好了
```
if (position != 0 && isEditMode && onDeleteData != null) {
String tag = labels.remove(position);
if (!tag.isEmpty()) {
onDeleteData.onDelete(tag);
//更新视图
notifyItemRemoved(position);
notifyItemRangeChanged(0,labels.size());
}
}
```