前提:依赖BaseRecyclerViewAdapterHelper
一、先说一下BaseQuickAdapter(单布局)的拖动排序
1、让自己的adapter继承BaseItemDraggableAdapter(继承了BaseQuickAdapter)
2、在自己的adapter set完成后添加拖拽回调并绑定给你的recyclerView,然后开启拖拽,并实现OnItemDragListener拖动监听的几个方法,如果你的页面有用到下拉刷新,需要在拖拽开启的时候禁掉下拉刷新,在拖拽完成的时候启用下拉刷新
HomeItemDragAndSwipeCallback itemDragAndSwipeCallback = new HomeItemDragAndSwipeCallback(adapter); ItemTouchHelper itemTouchHelper = new ItemTouchHelper(itemDragAndSwipeCallback); itemTouchHelper.attachToRecyclerView(recyclerView); // 开启拖拽 adapter.enableDragItem(itemTouchHelper); adapter.setOnItemDragListener(this);
@Override public void onItemDragStart(RecyclerView.ViewHolder viewHolder, int pos) { //开启拖拽的时候需要把下拉刷新禁掉 swipeRefreshLayout.setEnabled(false); swipeRefreshLayout.setRefreshing(false); mVibrator.vibrate(60); } @Override public void onItemDragMoving(RecyclerView.ViewHolder source, int from, RecyclerView.ViewHolder target, int to) { swipeRefreshLayout.setEnabled(false); swipeRefreshLayout.setRefreshing(false); } @Override public void onItemDragEnd(RecyclerView.ViewHolder viewHolder, int pos) { //拖拽完成重新恢复下拉刷新 swipeRefreshLayout.setEnabled(true); }
这样单布局item的拖拽就完成了,下面说下item多布局方式下(继承BaseMultiItemQuickAdapter的方式)如何实现拖动排序BaseRecyclerViewAdapterHelper本身只提供了item单布局方式的拖动排序,需要继承的是BaseItemDraggableAdapter,而BaseItemDraggableAdapter本身又继承于BaseQuickAdapter,然后我们再看一下BaseMultiItemQuickAdapter也是继承于BaseQuickAdapter,所以这就有了共性,我们就可以自己用它本身的代码以拼凑的形式自己完成一个多布局的可拖拽的adapter既然BaseItemDraggableAdapter继承于BaseQuickAdapter,我们就让自己的adapter继承BaseItemDraggableAdapter,然后再把BaseMultiItemQuickAdapter里面的代码复制到自己的adapter就可以了。具体代码如下:
public class BaseMultiItemDragQuickAdapterextends BaseItemDraggableAdapter { /** * layouts indexed with their types */ private SparseArray layouts; private static final int DEFAULT_VIEW_TYPE = -0xff; public static final int TYPE_NOT_FOUND = -404; /** * Same as QuickAdapter#QuickAdapter(Context,int) but with * some initialization data. * * @param data A new list is created out of this one to avoid mutable list */ public BaseMultiItemDragQuickAdapter(List data) { super(data); } @Override protected int getDefItemViewType(int position) { Object item = mData.get(position); if (item instanceof MultiItemEntity) { return ((MultiItemEntity) item).getItemType(); } return DEFAULT_VIEW_TYPE; } protected void setDefaultViewTypeLayout(@LayoutRes int layoutResId) { addItemType(DEFAULT_VIEW_TYPE, layoutResId); } @Override protected K onCreateDefViewHolder(ViewGroup parent, int viewType) { return createBaseViewHolder(parent, getLayoutId(viewType)); } private int getLayoutId(int viewType) { return layouts.get(viewType, TYPE_NOT_FOUND); } protected void addItemType(int type, @LayoutRes int layoutResId) { if (layouts == null) { layouts = new SparseArray<>(); } layouts.put(type, layoutResId); } @Override protected void convert(K helper, T item) { } /** * 重写BaseItemDraggableAdapter里面的onItemDragMoving方法,判断from Or to 是不是-1, * 当item拖动到头部的时候to是-1,必须判断,否则数组越界 * * @param source * @param target */ @Override public void onItemDragMoving(RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) { int from = getViewHolderPosition(source); int to = getViewHolderPosition(target); if (from == -1 || to == -1) { return; } super.onItemDragMoving(source, target); } }
其实说了这么多简单来说也就是让BaseMultiItemQuickAdapter直接继承BaseItemDraggableAdapter就行了,这里还需要注意以下几点问题:
1、一般我们的页面都不只是简单的一个recylcerView列表就完了,一般还会添加header甚至footer吧,自己试试可以知道,如果你把一个item拖动到header区域的时候就会报错啦,因为我们header区域的index一般情况下是-1,这就会导致数组下标越界,所以我们需要重写BaseItemDraggableAdapter里面的onItemDragMoving方法,然后做一下判断处理。
2、根据官方的说法,默认不支持多布局拖动,如果自己需要的话,需要重写ItemDragAndSwipeCallback让onMove方法返回true。
class HomeItemDragAndSwipeCallback extends ItemDragAndSwipeCallback { public HomeItemDragAndSwipeCallback(BaseItemDraggableAdapter adapter) { super(adapter); } @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) { return true; } }
这样就完成了