先看效果圖
demo下載 項目架構(gòu)為TheMVP
- 使用ItemTouchHelper 必須自己實現(xiàn) ItemTouchHelper.Callback 類
public class ItemDragHelperCallback extends ItemTouchHelper.Callback{
- 實現(xiàn)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);
}
- 實現(xiàn)ItemTouchHelper.Callback的onMove()和onSwiped()方法
//拖拽功能在這里實現(xiàn)
@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實現(xiàn) 然后針對數(shù)據(jù)的變動交由Adapter去具體實現(xiàn)
OnItemMoveListener listener = (OnItemMoveListener) recyclerView.getAdapter();
listener.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
}
return false;
}
/**
*滑動刪除的方法在這里實現(xiàn)(本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() 所對應的功能為滑動 和拖拽 根據(jù)需求是否開啟
@Override
public boolean isItemViewSwipeEnabled() {
// 不需要滑動功能
return false;
}
@Override
public boolean isLongPressDragEnabled() {
// 長按拖拽功能
return true;
}
- 最后 我們可以創(chuàng)建自己的ItemTouchHelper實例并調(diào)用attachToRecyclerView(RecyclerView)方法 就能實現(xiàn)該功能了
ItemDragHelperCallback callback=new ItemDragHelperCallback();
ItemTouchHelper helper=new ItemTouchHelper(callback);
itemHelper.attachToRecyclerView(top_recyclerView);
- 開過程中遇到的坑
- RecyclerView的item只能顯示一列由參數(shù)parent造成 在inflate(R.layout.item_label, null, false)中第二個參數(shù)不能傳parent 換為null就好了
//在inflate(R.layout.item_label, null, false)中第二個參數(shù)不能傳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數(shù)據(jù)時 造成集合數(shù)據(jù)position混亂是由 notifyItemRemoved(position);造成的 在后面再調(diào)用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());
}
}
```