相關(guān)的類(lèi)和方法
實(shí)現(xiàn)RecylerView的item可以上下拖動(dòng)和左右滑動(dòng)的效果需要使用類(lèi)ItemTouchHelper+ItemTouchHelper.Callback,其中Callback需要重寫(xiě)它的方法,其余就比較簡(jiǎn)單了,只需要下面3行代碼就可以實(shí)現(xiàn)"上下拖動(dòng)和左右滑動(dòng)刪除"
MyItemTouchCallback callback = new MyItemTouchCallback();
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
itemTouchHelper.attachToRecyclerView(recyclerView);
Step1: 自定義ItemTouchHelper.Callback
實(shí)現(xiàn)item的左右滑動(dòng)刪除和上下拖動(dòng)必須自定義ItemTouchHelper.Callback,而自定義Callback必須重寫(xiě)3個(gè)方法、getMovementFlags(...)、onMove(...)、onSwipe(...),而且需要傳入數(shù)據(jù)集合+adapter,如果不想傳這2個(gè)參數(shù),可以寫(xiě)個(gè)回調(diào)并且修改這3個(gè)方法(交給回調(diào)處理,在activity/fragment界面處理滑動(dòng)和拖動(dòng)時(shí)間)
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;
}
/**
* 設(shè)置ItemTouchHelper的類(lèi)型
*/
@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);
}
/**
* 上下拖動(dòng),
* return true;//可以滑動(dòng)
*/
@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有點(diǎn)擊事件的話(huà),會(huì)出錯(cuò)position,就不要用了
// adapter.notifyDataSetChanged();//沒(méi)有動(dòng)畫(huà)效果,但適用于item有點(diǎn)擊事件的話(huà)
return true;//true:可以滑動(dòng)
}
/**
* 左右滑動(dòng)刪除
*/
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
int position = viewHolder.getAdapterPosition();
mData.remove(position);
adapter.notifyItemRemoved(position);//局部更新,如果item有點(diǎn)擊事件的話(huà),會(huì)出錯(cuò)position,就不要用了
// adapter.notifyDataSetChanged();//沒(méi)有動(dòng)畫(huà)效果,但適用于item有點(diǎn)擊事件的話(huà)
}
}
Step2: 使用回調(diào)
@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);
}
同理,設(shè)置GridLayoutManager、StaggeredGridLayoutManager也是一樣的。
recyclerView.setLayoutManager(new GridLayoutManager(context,3));
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL));
問(wèn)題
1 當(dāng)我們上下拖動(dòng)或左右滑動(dòng)的時(shí)候,空白區(qū)域是白色,怎么設(shè)為其他顏色?
我們可以給RecyclerView設(shè)置android:background="@android:color/darker_gray"
2 notifyItemRemoved(position)+notifyItemMoved(fromPosition, toPosition)引起點(diǎn)擊事件bug?
第一張圖:上下滑動(dòng);第二張圖:左右滑動(dòng)。
其他
Demo:http://git.oschina.net/Android5x/itemtouchhelperdemo
參考: RecyclerView實(shí)現(xiàn)滑動(dòng)刪除和拖拽功能