我们先来看看效果图:
这里简单的RecyclerView列表就不说了,我们直接来重点,实现这个效果我们分两步:
一.实现条目拖拽 :鼠标点击条目的某一个控件(这里我选择的是条目中的image)不松开移动鼠标,条目跟着动.
1.如何开启条目拖动呢?很简单,调用
ItemTouchHelper.startDrag(ViewHolder viewHolder);
2.在什么条件下开启条目拖动呢?
((MyViewHoder)viewHolder).imageView.setOnTouchListener(new OnTouchListener() {
@Override
public 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 {
@Override
public int getMovementFlags(RecyclerView recyclerView,ViewHolder viewHolder) {
// TODO Auto-generated method stub
// Flags 是十六进制的运算结果
// CallBack回调监听时先调用的 用来判断当前是什么动作比如判断方向(意思是我要监听哪个方向的拖动)
// 方向: up 、down 、 left 、right
// 多个方向时 返回的还是一个值 所以这里存在 与运算(&)和 或运算(|) 0:表示"非" 1:表示"是"
int up = ItemTouchHelper.UP;// 1:0x0001
int down = ItemTouchHelper.DOWN;// 2:0x0010
int dragFlags = up | down;
/**
* drags : 拖拽(up/down)
* swipe : 侧滑(lef/fight)
* makeMovementFlags(dragFlags, swipeFlags);
* **/
return makeMovementFlags(dragFlags, 0);
}
}
3.在哪里调用ItemTouchHelper.startDrag(ViewHolder viewHolder);最合适?
public interface StartDragListener {
/**
* 该接口用于主动回调拖拽效果
* @param viewHolder
*/
public void onStartDrag(ViewHolder viewHolder);
}
在拥有ItemTouchHelper的Activity中实现回调,调用ItemTouchHelper.startDrag(ViewHolder viewHolder);开启拖拽
@Override
public void onStartDrag(ViewHolder viewHolder){
//开启条目拖动
itemTouchHelper.startDrag(viewHolder);
}
二.实现排序(就是讲条目拖拽到某个位置松开后嵌入该位置)
首先我们知道我们的RecyclerView的:
Adapter.notifyItemMoved(int fromPosition,int toPosition);
可以实现,所以我们要在条目移动的时候调用该方法,所以我们现在依然要创建一个借口用于连接ItemTouchHelper.Callback和Adapter:
public interface ItemTouchMoveListener {
/**
* 当拖拽的时候回调此方法
* 在此方法中可以实现:拖拽条目并实现刷新效果
* @param fromPosition 从什么位置
* @param toPosition 到什么位置
* @return 是否回调
*/
public boolean onItemMove(int fromPosition,int toPosition);
}
在Adapter中实现:
@Override
public boolean onItemMove(int fromPosition, int toPosition) {
// 1. 数据交换 2. 刷新RecyclerView
Collections.swap(mDatas, fromPosition, toPosition);
notifyItemMoved(fromPosition, toPosition);
return true;
}
@Override
public 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;
}