1.概述
這是春節(jié)前的最后一篇分享技術(shù)的博客了,接下來(lái)的時(shí)間需要去完善視頻講解,至于今年都干了哪些事有什么成就吹牛的這里就不多說(shuō)了,聲明一下圖片資源我是盜用的別人的。這是最后一期分享RecyclerView了,我們直接看這一期需要分享的效果:
視頻講解:http://pan.baidu.com/s/1jIlwl4E
相關(guān)文章:
RecyclerView更全解析之 - 基本使用和分割線解析
RecyclerView更全解析之 - 打造通用的萬(wàn)能Adapter
RecyclerView更全解析之 - 為它優(yōu)雅的添加頭部和底部
RecyclerView更全解析之 - 打造通用的下拉刷新上拉加載
RecyclerView更全解析之 - 仿支付寶側(cè)滑刪除和拖動(dòng)排序
2.基本思路
前面我們一直都是圍著RecyclerView在轉(zhuǎn),發(fā)現(xiàn)這個(gè)控件讓我們是又愛(ài)又恨,通過(guò)這幾期的分享或者說(shuō)是封裝應(yīng)該已經(jīng)讓我們喜歡上它了,那么今天我們?cè)趤?lái)看一個(gè)如此神奇的功能。我記得當(dāng)初在做ListView的拖動(dòng)排序的時(shí)候在網(wǎng)上找了各種資料,代碼量還真不是一丁點(diǎn),現(xiàn)在我們來(lái)看一下RecyclerView的拖動(dòng)排序和側(cè)滑刪除需要怎么去實(shí)現(xiàn),告訴你只需要簡(jiǎn)簡(jiǎn)單單的幾行代碼。
實(shí)現(xiàn)這么個(gè)功能我們不需要再去繼承RecyclerView,只需要去了解ItemTouchHelper這個(gè)類即可,接下來(lái)我們就去看看都有些什么。
3.基本實(shí)現(xiàn)
3.1 實(shí)現(xiàn)側(cè)滑刪除
ItemTouchHelper這是google給我們寫好的,專門用來(lái)處理Touch相關(guān)的一個(gè)類,我們先來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的功能側(cè)滑刪除,先上代碼再解釋:
// 實(shí)現(xiàn)左邊側(cè)滑刪除
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
// 獲取觸摸響應(yīng)的方向 包含兩個(gè) 1.拖動(dòng)dragFlags 2.側(cè)滑刪除swipeFlags
// 代表只能是向左側(cè)滑刪除,當(dāng)前可以是這樣ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT
int swipeFlags = ItemTouchHelper.LEFT;
// 拖動(dòng)暫不處理默認(rèn)是0
return makeMovementFlags(0, swipeFlags);
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
}
});
// 這個(gè)就不多解釋了,就這么attach
itemTouchHelper.attachToRecyclerView(mRecyclerView);
ItemTouchHelper.Callback 默認(rèn)需要實(shí)現(xiàn)三個(gè)方法:
getMovementFlags() 獲取Touch的響應(yīng)方向,包含兩個(gè) 1.拖動(dòng)dragFlags 2.側(cè)滑刪除swipeFlags,都可以是上下左右,上面事例沒(méi)有處理拖動(dòng)所以傳的是0,側(cè)滑給的是ItemTouchHelper.LEFT,所以待會(huì)效果是向左滑動(dòng)刪除;
onMove() 拖動(dòng)的時(shí)候會(huì)不斷的回調(diào)這個(gè)方法,拖動(dòng)的時(shí)候肯定需要不斷的更新列表數(shù)據(jù),達(dá)到一邊拖動(dòng)列表不斷更新當(dāng)前數(shù)據(jù);
onSwiped() 側(cè)滑刪除之后的回調(diào)方法。
目前的效果可以側(cè)滑刪除但是發(fā)現(xiàn)列表不更新,而且側(cè)滑的時(shí)候不高亮,當(dāng)然如果你不想要高亮那就不處理,再來(lái)改改:
// 實(shí)現(xiàn)左邊側(cè)滑刪除
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
// 獲取觸摸響應(yīng)的方向 包含兩個(gè) 1.拖動(dòng)dragFlags 2.側(cè)滑刪除swipeFlags
// 代表只能是向左側(cè)滑刪除,當(dāng)前可以是這樣ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT
int swipeFlags = ItemTouchHelper.LEFT;
// 拖動(dòng)暫不處理默認(rèn)是0
return makeMovementFlags(0, swipeFlags);
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
/**
* 側(cè)滑刪除后會(huì)回調(diào)的方法
*/
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
// 獲取當(dāng)前刪除的位置
int position = viewHolder.getAdapterPosition();
mItems.remove(position);
// adapter 更新notify當(dāng)前位置刪除
mAdapter.notifyDataSetChanged();
}
/**
* 拖動(dòng)選擇狀態(tài)改變回調(diào)
*/
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
// ItemTouchHelper.ACTION_STATE_IDLE 看看源碼解釋就能理解了
// 側(cè)滑或者拖動(dòng)的時(shí)候背景設(shè)置為灰色
viewHolder.itemView.setBackgroundColor(Color.GRAY);
}
}
/**
* 回到正常狀態(tài)的時(shí)候回調(diào)
*/
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
// 正常默認(rèn)狀態(tài)下背景恢復(fù)默認(rèn)
viewHolder.itemView.setBackgroundColor(0);
}
});
// 這個(gè)就不多解釋了,就這么attach
itemTouchHelper.attachToRecyclerView(mRecyclerView);
3.2 實(shí)現(xiàn)拖動(dòng)排序
上面有兩個(gè)方法onSelectedChanged(),clearView()不做過(guò)多的介紹,接下來(lái)實(shí)現(xiàn)拖動(dòng)排序,還是我們?cè)谏厦娴拇a基礎(chǔ)山做一下修改,需要修改兩個(gè)方法:
getMovementFlags() 的dragFlags參數(shù)不能傳0了,側(cè)滑的時(shí)候沒(méi)處理現(xiàn)在需要處理一下了;
onMove() 在拖動(dòng)的時(shí)候不斷的回調(diào)改變列表的位置,不光要改變位置還要不斷的改變數(shù)據(jù)集合的列表。
// 實(shí)現(xiàn)左邊側(cè)滑刪除 和 拖動(dòng)排序
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
// 獲取觸摸響應(yīng)的方向 包含兩個(gè) 1.拖動(dòng)dragFlags 2.側(cè)滑刪除swipeFlags
// 代表只能是向左側(cè)滑刪除,當(dāng)前可以是這樣ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT
int swipeFlags = ItemTouchHelper.LEFT;
// 拖動(dòng)
int dragFlags = 0;
if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
// GridView 樣式四個(gè)方向都可以
dragFlags = ItemTouchHelper.UP | ItemTouchHelper.LEFT |
ItemTouchHelper.DOWN | ItemTouchHelper.RIGHT;
} else {
// ListView 樣式不支持左右,只支持上下
dragFlags = ItemTouchHelper.UP |
ItemTouchHelper.DOWN;
}
return makeMovementFlags(dragFlags, swipeFlags);
}
/**
* 拖動(dòng)的時(shí)候不斷的回調(diào)方法
*/
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
// 獲取原來(lái)的位置
int fromPosition = viewHolder.getAdapterPosition();
// 得到目標(biāo)的位置
int targetPosition = target.getAdapterPosition();
if (fromPosition > targetPosition) {
for (int i = fromPosition; i < targetPosition; i++) {
Collections.swap(mItems, i, i + 1);// 改變實(shí)際的數(shù)據(jù)集
}
} else {
for (int i = fromPosition; i > targetPosition; i--) {
Collections.swap(mItems, i, i - 1);// 改變實(shí)際的數(shù)據(jù)集
}
}
mAdapter.notifyItemMoved(fromPosition, targetPosition);
return true;
}
/**
* 側(cè)滑刪除后會(huì)回調(diào)的方法
*/
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
// 獲取當(dāng)前刪除的位置
int position = viewHolder.getAdapterPosition();
mItems.remove(position);
// adapter 更新notify當(dāng)前位置刪除
mAdapter.notifyItemRemoved(position);
}
/**
* 拖動(dòng)選擇狀態(tài)改變回調(diào)
*/
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
// ItemTouchHelper.ACTION_STATE_IDLE 看看源碼解釋就能理解了
// 側(cè)滑或者拖動(dòng)的時(shí)候背景設(shè)置為灰色
viewHolder.itemView.setBackgroundColor(Color.GRAY);
}
}
/**
* 回到正常狀態(tài)的時(shí)候回調(diào)
*/
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
// 正常默認(rèn)狀態(tài)下背景恢復(fù)默認(rèn)
viewHolder.itemView.setBackgroundColor(0);
ViewCompat.setTranslationX(viewHolder.itemView,0);
}
});
// 這個(gè)就不多解釋了,就這么attach
itemTouchHelper.attachToRecyclerView(mRecyclerView);
附視頻地址:http://pan.baidu.com/s/1jHW1X10