Android一步步帶你在RecyclerView上面實現(xiàn)"拖放"和"滑動刪除"功能
先給大家展示下大概效果圖:

Android上面有許多的教程, 庫和示例, 在RecyclerView上面實現(xiàn)"拖放"和"滑動刪除"功能. 盡管有更新, 更好的方法可用, 但是大多數(shù)人依然使用舊的View.OnDragListener和Roman Nurik的SwipeToDismiss方式. 除了經(jīng)常使用GestureDetector和onInterceptTouchEvent之外, 幾乎很少有人使用新的API, 要不然的話, 實現(xiàn)就復(fù)雜. 事實上真的有十分簡單的方式在RecyclerView上面添加這兩個功能. 它只要求一個類, 而且這個類已經(jīng)是Android支持包的一部分.
ItemTouchHelper是一個強大的通用程序, 在RecyclerView上面添加"拖放"和"滑動刪除"時, 你所需要做的所有事情, 它都會負責(zé)處理. 它是RecyclerView.ItemDecoration的子類, 這意味著它可以輕易地添加到任何已經(jīng)存在的LayoutManager和Adapter上面! 它不會影響添加到item上的動畫, 并且支持類別嚴格的"拖", 以及"放"時的動畫, 還可以支持更多.
準備:
首先, 我們所需要的是添加RecyclerView的依賴:
compile 'com.android.support:recyclerview-v7:25.3.0'
使用ItemTouchHelper和ItemTouchHelper.Callback:
為了使用ItemTouchHelper, 你將創(chuàng)建一個ItemTouchHelper.Callback, 這是一個接口, 允許你監(jiān)聽"move"和"swipe"事件, 而且你可以通過Callback來控件已選中view的狀態(tài), 并且可以改變該view的默認動畫. 如果只是想要一個基礎(chǔ)實現(xiàn), 你可以使用SimpleCallback這個幫助類, 但是為了學(xué)習(xí)Callback的工作原理, 我們將會自己實現(xiàn)一個.
為了激活基本的"拖放"和"滑動刪除", 我們必須覆蓋的主要方法是:
getMovementFlags(RecyclerView, ViewHolder) onMove(RecyclerView, ViewHolder, ViewHolder) onSwiped(ViewHolder, int)
我們也要使用這兩個方法:
isLongPressDragEnabled() isItemViewSwipeEnabled()
我們一個一個地看一下:
@Override
public int getMovementFlags(RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder) {
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
return makeMovementFlags(dragFlags, swipeFlags);
}
ItemTouchHelper允許你輕易地決定事件的方向.你必須實現(xiàn)getMovementFlags(RecyclerView, RecyclerView.ViewHolder)方法來指明"拖"和"滑動"所支持的方向, 并且使用ItemTouchHelper.makeMovementFlags(int, int)來構(gòu)建返回標簽. 在此我們在兩個不同的方向激活"拖"和"滑動".
@Override
public boolean isLongPressDragEnabled() {
return true;
}
ItemTouchHelper能夠用來實現(xiàn)"沒有滑動的拖動"或者"沒有拖動的滑動", 所以你必須精確地指明想要支持的動作. 如果你想要在RecyclerView的item上支持"長按啟動拖放"事件, 你就必須實現(xiàn)isLongPressDragEnabled()返回true. 此外, ItemTouchHelper.startDrag(RecyclerView.ViewHolder)可以從"操作"中啟動"拖放", 這一點會在之后詳述.
@Override
public boolean isItemViewSwipeEnabled() {
return true;
}
要想要view內(nèi)部的任意觸摸事件都可以啟動"滑動"動作, 就簡單地在isItemViewSwipeEnabled()返回true. 此外, ItemTouchHelper.startSwipe(RecyclerView.ViewHolder)能夠手動地啟動"滑動"事件.
然后, onMove()和onSwiped()方法需要實現(xiàn), 來通知負責(zé)更新基礎(chǔ)數(shù)據(jù)的東西. 所以, 首先, 我們要創(chuàng)建一個接口, 以允許我們傳遞"拖放"和"滑動刪除"事件的回調(diào).
public interface ItemTouchHelperAdapter {
void onItemMove(int fromPosition, int toPosition);
void onItemDismiss(int position);
}
從當(dāng)前示例來講, 要實現(xiàn)這些的最簡單的方式, 是將我們的RecyclerView.Adapter實現(xiàn)這個接口:
public class RecyclerListAdapter extends
RecyclerView.Adapter<ItemViewHolder>
implements ItemTouchHelperAdapter {
// ... code from gist
@Override
public void onItemDismiss(int position) {
mItems.remove(position);
notifyItemRemoved(position);
}
@Override
public boolean onItemMove(int fromPosition, int toPosition) {
if (fromPosition < toPosition) {
for (int i = fromPosition; i < toPosition; i++) {
Collections.swap(mItems, i, i + 1);
}
} else {
for (int i = fromPosition; i > toPosition; i--) {
Collections.swap(mItems, i, i - 1);
}
}
notifyItemMoved(fromPosition, toPosition);
return true;
}
調(diào)用notifyItemRemoved(int)和notifyItemMoved(int, int)是非常重要的, 由此, Adapter會更新數(shù)據(jù). 請注意, 這也很重要, 我們改變item的position是在每一次view被切換到新的index, 而不是在"放"事件之后.
現(xiàn)在我們回來構(gòu)建SimpleItemTouchHelperCallback, 因為我們依然必須覆蓋onMove()和onSwiped()方法. 首先, 為Adapter添加構(gòu)建器和變量:
private final ItemTouchHelperAdapter mAdapter;
public SimpleItemTouchHelperCallback(
ItemTouchHelperAdapter adapter) {
mAdapter = adapter;
}
然后覆蓋剩下的事件并通知Adapter:
@Override
public boolean onMove(RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder,
RecyclerView.ViewHolder target) {
mAdapter.onItemMove(viewHolder.getAdapterPosition(),
target.getAdapterPosition());
return true;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder,
int direction) {
mAdapter.onItemDismiss(viewHolder.getAdapterPosition());
}
這個Callback應(yīng)該看起來像這樣:
public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
private final ItemTouchHelperAdapter mAdapter;
public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter) {
mAdapter = adapter;
}
@Override
public boolean isLongPressDragEnabled() {
return true;
}
@Override
public boolean isItemViewSwipeEnabled() {
return true;
}
@Override
public int getMovementFlags(RecyclerView recyclerView, ViewHolder viewHolder) {
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
return makeMovementFlags(dragFlags, swipeFlags);
}
@Override
public boolean onMove(RecyclerView recyclerView, ViewHolder viewHolder,
ViewHolder target) {
mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return true;
}
@Override
public void onSwiped(ViewHolder viewHolder, int direction) {
mAdapter.onItemDismiss(viewHolder.getAdapterPosition());
}
}
當(dāng)Callback準備好之后, 我們創(chuàng)建ItemTouchHelper并調(diào)用attachToRecyclerView(RecyclerView)方法:
ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(adapter); ItemTouchHelper touchHelper = new ItemTouchHelper(callback); touchHelper.attachToRecyclerView(recyclerView);
當(dāng)你運行的時候, 結(jié)果應(yīng)該看起來像這樣:

總結(jié)
這是一個ItemTouchHelper極簡單的實現(xiàn). 但是我們應(yīng)該清楚, 在RecyclerView上面實現(xiàn)基本的"拖放"和"滑動刪除", 使用第三方和庫是完全沒有必要的.
以上所述是小編給大家介紹的Android一步步帶你在RecyclerView上面實現(xiàn)"拖放"和"滑動刪除"功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
unity5.6 導(dǎo)出gradle工程 Android Studio 導(dǎo)入問題及處理方法
這篇文章主要介紹了unity5.6 導(dǎo)出gradle工程 Android Studio 導(dǎo)入問題及處理方法,需要的朋友可以參考下2017-12-12
Android實現(xiàn)點擊WebView界面中圖片滑動瀏覽與保存圖片功能
大家在日常使用spp流量文章的時候經(jīng)常會遇到這樣的一個功能,點擊文章的圖片進入圖片的瀏覽模式,可以左右滑動圖片瀏覽,并且可以實現(xiàn)保存圖片的功能,所以本文主要就介紹了在Android如何實現(xiàn)點擊WebView界面中圖片滑動瀏覽與保存圖片功能,需要的朋友可以參考下。2017-04-04
Android ViewPager實現(xiàn)滑動指示條功能
這篇文章主要介紹了Android-ViewPager實現(xiàn)滑動指示條功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10
Android 使用Toolbar實現(xiàn)應(yīng)用欄實例詳解
這篇文章主要為大家介紹了Android 使用Toolbar實現(xiàn)應(yīng)用欄實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11

