ItemTouchHelper
最近看其他项目中总会看到这个效果,『拖拽排序,拖拽删除』,其实这个效果放在以前的话是比较难做的,现在Google在support-v7包中添加了这个Helper,使得现在做这个效果很简单
可以看到我工程名字起的就是RecyclerViewDrag,所以就可以看的出来这个Helper是和RecyclerView一起工作的,从Google官方文档我们也可以看到这样两句话:
『This is a utility class to add swipe to dismiss and drag & drop support to RecyclerView.』
『Depending on which functionality you support, you should override onMove(RecyclerView, ViewHolder, ViewHolder) and / or onSwiped(ViewHolder, int).』
大致意思就是这个工具类可以支持RecyclerView的拖拽和消除,根据你的需求应该要重写onMove或者onSwiped这两个方法,所以根据剧情需要,我们来重写这两个方法。
但是在重写这两个方法之前我们首先应该看一下onMove()和onSwiped()这两个方法,而这两个方法是在ItemTouchHelper的内部类Callback中,所以我们跟进官方文档,可以看到下面这段话:
『If user drags an item, ItemTouchHelper will call onMove(recyclerView, dragged, target). Upon receiving this callback, you should move the item from the old position (dragged.getAdapterPosition()) to new position (target.getAdapterPosition()) in your adapter and also call notifyItemMoved(int, int)』
这么长一大段,我以小学英语水平大致看了一下,差不多的意思就是说『如果用户拖动了某一个Item,那么就会回调onMove这个方法,而在收到这个回调的时候我们应该让RecyclerView做一些事情,比如从旧的位置(dragged.getAdapterPosition())到新的位置(target.getAdapterPosition()),然后在你的adapter中调用notifyItemMoved(int, int)方法』
大致就是这个意思,反正我看不太懂
所以我们应该能有点思路,就是拖动的时候要回调onMove()方法,然后我们根据这个方法来回调参数进行我们的操作,这首先就想到了接口,所以我们定义一个接口:
public interface OnItemCallbackListener {
/**
* @param fromPosition 起始位置
* @param toPosition 移动的位置
*/
void onMove(int fromPosition, int toPosition);
void onSwipe(int position);
}
然后在onMove()/onSwiped()方法中回调
/**
* Item是否能被Swipe到dismiss
* 也就是删除这条数据
*/
@Override
public boolean isItemViewSwipeEnabled() {
return true;
}
/**
* Item长按是否可以拖拽
*/
@Override
public boolean isLongPressDragEnabled() {
return true;
}
/**
* 设置Drag/Swipe的Flag
* 这里我们把滑动(Drag)的四个方向全都设置上了,说明Item可以随意移动
* 然后把删除(暂且叫删除/swipe)的方向设置为Start和End,说明可以水平拖动删除
*/
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
int dragFlag = ItemTouchHelper.LEFT | ItemTouchHelper.DOWN | ItemTouchHelper.UP | ItemTouchHelper.RIGHT;
int swipeFlag = ItemTouchHelper.START | ItemTouchHelper.END;
return makeMovementFlags(dragFlag, swipeFlag);
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
/**
* 回调
*/
adapter.onMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return true;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
/**
* 回调
*/
adapter.onSwipe(viewHolder.getAdapterPosition());
}
然后我们定义一个自己的adapter来实现这个接口,代码如下:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.Holder> implements OnItemCallbackListener{
private List<String> mData;
private Context mContext;
public MyAdapter(Context mContext) {
this.mContext = mContext;
mData = new ArrayList<>();
mData.add("one");
mData.add("two");
mData.add("three");
mData.add("four");
mData.add("five");
mData.add("six");
mData.add("seven");
}
@Override
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.adapter_test, parent, false);
return new Holder(view);
}
@Override
public void onBindViewHolder(final Holder holder, int position) {
holder.tv.setText(mData.get(position));
}
@Override
public int getItemCount() {
return mData.size();
}
@Override
public void onMove(int fromPosition, int toPosition) {
/**
* 在这里进行给原数组数据的移动
*/
Collections.swap(mData, fromPosition, toPosition);
/**
* 通知数据移动
*/
notifyItemMoved(fromPosition, toPosition);
}
@Override
public void onSwipe(int position) {
/**
* 原数据移除数据
*/
mData.remove(position);
/**
* 通知移除
*/
notifyItemRemoved(position);
}
class Holder extends RecyclerView.ViewHolder {
TextView tv;
public Holder(View itemView) {
super(itemView);
tv = (TextView) itemView.findViewById(R.id.tv);
}
}
}
最后在Activity中:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView rv = (RecyclerView) findViewById(R.id.rv);
rv.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
final MyAdapter adapter = new MyAdapter(this);
rv.setAdapter(adapter);
ItemTouchHelper.Callback callback = new OnItemCallbackHelper(adapter);
/**
* 实例化ItemTouchHelper对象,然后添加到RecyclerView
*/
ItemTouchHelper helper = new ItemTouchHelper(callback);
helper.attachToRecyclerView(rv);
}
这样一个最简单的拖拽滑动、删除的效果就完成了,其实还可以设置RecyclerView的其他LayoutManager,这里就不过多做解释了,有兴趣的可以试试
最后
爱生活,爱小丽,爱Android
网友评论
{
return;
}