RecyclerView之使用ItemTouchHelper和ItemTouchHelper.Callback实现条目拖拽排序

来源:互联网 发布:2017淘宝新店提取软件 编辑:程序博客网 时间:2024/04/30 00:07

我们先来看看效果图:


这里简单的RecyclerView列表就不说了,我们直接来重点,实现这个效果我们分两步:

一.实现条目拖拽 :鼠标点击条目的某一个控件(这里我选择的是条目中的image)不松开移动鼠标,条目跟着动.

1.如何开启条目拖动呢?很简单,调用

 ItemTouchHelper.startDrag(ViewHolder viewHolder);
2.在什么条件下开启条目拖动呢?
a.鼠标要点击image不松开 
((MyViewHoder)viewHolder).imageView.setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {if (event.getAction()==MotionEvent.ACTION_DOWN) {// 传递触摸情况给ItemTouchHelper  调用 ItemTouchHelper.startDrags()方法if (mStartDragListener!=null) {mStartDragListener.onStartDrag(viewHolder);}}return false;}});
b. 不松开之后做上下移动的动作时需要ItemTouchHelper开启回调
 public class MyItemTouchCallBack extends Callback {@Overridepublic int getMovementFlags(RecyclerView recyclerView,ViewHolder viewHolder) {// TODO Auto-generated method stub// Flags  是十六进制的运算结果// CallBack回调监听时先调用的  用来判断当前是什么动作比如判断方向(意思是我要监听哪个方向的拖动)// 方向: up 、down 、 left 、right// 多个方向时 返回的还是一个值  所以这里存在   与运算(&)和 或运算(|)       0:表示"非"  1:表示"是"int up = ItemTouchHelper.UP;//      1:0x0001int down = ItemTouchHelper.DOWN;//  2:0x0010int dragFlags = up | down;/** * drags :  拖拽(up/down) * swipe :  侧滑(lef/fight) * makeMovementFlags(dragFlags, swipeFlags); * **/return makeMovementFlags(dragFlags, 0);} }
3.在哪里调用ItemTouchHelper.startDrag(ViewHolder viewHolder);最合适?
  看参数我们就知道要在adapter中调用方便,但是将ItemTouchHelper传入Adapter中太low了 
  所以两个类的连接我们用interface 连接所以我们创建一个接口(作用就是当我们短按摸个条目的image是将此时的ViewHolder传递到拥有ItemTouchHelper的activity调用startDrag方法):
 public interface StartDragListener {/** * 该接口用于主动回调拖拽效果 * @param viewHolder */public void  onStartDrag(ViewHolder viewHolder); }
 在拥有ItemTouchHelper的Activity中实现回调,调用ItemTouchHelper.startDrag(ViewHolder viewHolder);开启拖拽

@Overridepublic void onStartDrag(ViewHolder viewHolder){    //开启条目拖动    itemTouchHelper.startDrag(viewHolder);}

二.实现排序(就是讲条目拖拽到某个位置松开后嵌入该位置)

 首先我们知道我们的RecyclerView的:

Adapter.notifyItemMoved(int fromPosition,int  toPosition);
可以实现,所以我们要在条目移动的时候调用该方法,所以我们现在依然要创建一个借口用于连接ItemTouchHelper.Callback和Adapter:

public interface ItemTouchMoveListener {/** * 当拖拽的时候回调此方法<br> * 在此方法中可以实现:拖拽条目并实现刷新效果 * @param fromPosition 从什么位置 * @param toPosition 到什么位置 * @return 是否回调 */public boolean onItemMove(int fromPosition,int toPosition);}
在Adapter中实现:

@Overridepublic boolean onItemMove(int fromPosition, int toPosition) {// 1. 数据交换  2. 刷新RecyclerViewCollections.swap(mDatas, fromPosition, toPosition);notifyItemMoved(fromPosition, toPosition);return true;}

在ItemTouchHelper.Callback.的move方法中调用:

@Overridepublic boolean onMove(RecyclerView recyclerView,ViewHolder viewHolder, ViewHolder target) {// TODO Auto-generated method stub// 当移动的时候回调的方法if (viewHolder.getItemViewType()!=target.getItemViewType()) {//不同的条目不进行交换return false;}mItemTouchMoveListener.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());return true;}





1 0
原创粉丝点击