相关的类和方法
实现RecylerView
的item可以上下拖动和左右滑动的效果需要使用类ItemTouchHelper
+ItemTouchHelper.Callback
,其中Callback
需要重写它的方法,其余就比较简单了,只需要下面3行代码就可以实现"上下拖动和左右滑动删除"
MyItemTouchCallback callback = new MyItemTouchCallback();
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
itemTouchHelper.attachToRecyclerView(recyclerView);
Step1: 自定义ItemTouchHelper.Callback
实现item的左右滑动删除和上下拖动必须自定义ItemTouchHelper.Callback,而自定义Callback必须重写3个方法、getMovementFlags(...)
、onMove(...)
、onSwipe(...)
,而且需要传入数据集合+adapter,如果不想传这2个参数,可以写个回调并且修改这3个方法(交给回调处理,在activity/fragment界面处理滑动和拖动时间)
public class MyItemTouchCallback extends ItemTouchHelper.Callback {
private RecyclerViewAdapter adapter;
private List<String> mData;
public MyItemTouchCallback(RecyclerViewAdapter adapter, List<String> mData) {
this.adapter = adapter;
this.mData = mData;
}
/**
* 设置ItemTouchHelper的类型
*/
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
int swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
return makeMovementFlags(dragFlags, swipeFlags);
}
/**
* 上下拖动,
* return true;//可以滑动
*/
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
int fromPosition = viewHolder.getAdapterPosition();
int toPosition = target.getAdapterPosition();
Collections.swap(mData, fromPosition, toPosition);
adapter.notifyItemMoved(fromPosition, toPosition);//局部更新,如果item有点击事件的话,会出错position,就不要用了
// adapter.notifyDataSetChanged();//没有动画效果,但适用于item有点击事件的话
return true;//true:可以滑动
}
/**
* 左右滑动删除
*/
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
int position = viewHolder.getAdapterPosition();
mData.remove(position);
adapter.notifyItemRemoved(position);//局部更新,如果item有点击事件的话,会出错position,就不要用了
// adapter.notifyDataSetChanged();//没有动画效果,但适用于item有点击事件的话
}
}
Step2: 使用回调
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
initData();
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.addItemDecoration(new DividerItemDecoration(context,LinearLayoutManager.VERTICAL));
RecyclerViewAdapter adapter = new RecyclerViewAdapter(mData);
recyclerView.setAdapter(adapter);
adapter.setOnItemClickListener(new RecyclerViewAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
ToastUtil.showShortToast(context,""+position);
}
});
MyItemTouchCallback callback = new MyItemTouchCallback(adapter,mData);
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
itemTouchHelper.attachToRecyclerView(recyclerView);
}
同理,设置GridLayoutManager
、StaggeredGridLayoutManager
也是一样的。
recyclerView.setLayoutManager(new GridLayoutManager(context,3));
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL));
问题
1 当我们上下拖动或左右滑动的时候,空白区域是白色,怎么设为其他颜色?
我们可以给RecyclerView设置android:background="@android:color/darker_gray"
2 notifyItemRemoved(position)+notifyItemMoved(fromPosition, toPosition)引起点击事件bug?
第一张图:上下滑动;第二张图:左右滑动。
其他
Demo:http://git.oschina.net/Android5x/itemtouchhelperdemo
参考: RecyclerView实现滑动删除和拖拽功能