国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android一步步帶你在RecyclerView上面實現"拖放"和"滑動刪除"功能

2019-12-12 03:18:41
字體:
來源:轉載
供稿:網友

先給大家展示下大概效果圖:

Android上面有許多的教程, 庫和示例, 在RecyclerView上面實現"拖放"和"滑動刪除"功能. 盡管有更新, 更好的方法可用, 但是大多數人依然使用舊的View.OnDragListener和Roman Nurik的SwipeToDismiss方式. 除了經常使用GestureDetector和onInterceptTouchEvent之外, 幾乎很少有人使用新的API, 要不然的話, 實現就復雜. 事實上真的有十分簡單的方式在RecyclerView上面添加這兩個功能. 它只要求一個類, 而且這個類已經是Android支持包的一部分.

ItemTouchHelper

ItemTouchHelper是一個強大的通用程序, 在RecyclerView上面添加"拖放"和"滑動刪除"時, 你所需要做的所有事情, 它都會負責處理. 它是RecyclerView.ItemDecoration的子類, 這意味著它可以輕易地添加到任何已經存在的LayoutManager和Adapter上面! 它不會影響添加到item上的動畫, 并且支持類別嚴格的"拖", 以及"放"時的動畫, 還可以支持更多.

準備:

首先, 我們所需要的是添加RecyclerView的依賴:

 compile 'com.android.support:recyclerview-v7:25.3.0'

使用ItemTouchHelper和ItemTouchHelper.Callback:

為了使用ItemTouchHelper, 你將創建一個ItemTouchHelper.Callback, 這是一個接口, 允許你監聽"move"和"swipe"事件, 而且你可以通過Callback來控件已選中view的狀態, 并且可以改變該view的默認動畫. 如果只是想要一個基礎實現, 你可以使用SimpleCallback這個幫助類, 但是為了學習Callback的工作原理, 我們將會自己實現一個.

為了激活基本的"拖放"和"滑動刪除", 我們必須覆蓋的主要方法是:

getMovementFlags(RecyclerView, ViewHolder)onMove(RecyclerView, ViewHolder, ViewHolder)onSwiped(ViewHolder, int)

我們也要使用這兩個方法:

isLongPressDragEnabled()isItemViewSwipeEnabled()

我們一個一個地看一下:

@Overridepublic int getMovementFlags(RecyclerView recyclerView,   RecyclerView.ViewHolder viewHolder) { int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; return makeMovementFlags(dragFlags, swipeFlags);}

ItemTouchHelper允許你輕易地決定事件的方向.你必須實現getMovementFlags(RecyclerView, RecyclerView.ViewHolder)方法來指明"拖"和"滑動"所支持的方向, 并且使用ItemTouchHelper.makeMovementFlags(int, int)來構建返回標簽. 在此我們在兩個不同的方向激活"拖"和"滑動".

@Overridepublic boolean isLongPressDragEnabled() { return true;}

ItemTouchHelper能夠用來實現"沒有滑動的拖動"或者"沒有拖動的滑動", 所以你必須精確地指明想要支持的動作. 如果你想要在RecyclerView的item上支持"長按啟動拖放"事件, 你就必須實現isLongPressDragEnabled()返回true. 此外, ItemTouchHelper.startDrag(RecyclerView.ViewHolder)可以從"操作"中啟動"拖放", 這一點會在之后詳述.

@Overridepublic boolean isItemViewSwipeEnabled() { return true;}

要想要view內部的任意觸摸事件都可以啟動"滑動"動作, 就簡單地在isItemViewSwipeEnabled()返回true. 此外, ItemTouchHelper.startSwipe(RecyclerView.ViewHolder)能夠手動地啟動"滑動"事件.

然后, onMove()和onSwiped()方法需要實現, 來通知負責更新基礎數據的東西. 所以, 首先, 我們要創建一個接口, 以允許我們傳遞"拖放"和"滑動刪除"事件的回調.

public interface ItemTouchHelperAdapter { void onItemMove(int fromPosition, int toPosition); void onItemDismiss(int position);}

從當前示例來講, 要實現這些的最簡單的方式, 是將我們的RecyclerView.Adapter實現這個接口:

public class RecyclerListAdapter extends   RecyclerView.Adapter<ItemViewHolder>   implements ItemTouchHelperAdapter {// ... code from gist@Overridepublic void onItemDismiss(int position) { mItems.remove(position); notifyItemRemoved(position);}@Overridepublic 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;}

調用notifyItemRemoved(int)和notifyItemMoved(int, int)是非常重要的, 由此, Adapter會更新數據. 請注意, 這也很重要, 我們改變item的position是在每一次view被切換到新的index, 而不是在"放"事件之后.

現在我們回來構建SimpleItemTouchHelperCallback, 因為我們依然必須覆蓋onMove()和onSwiped()方法. 首先, 為Adapter添加構建器和變量:

private final ItemTouchHelperAdapter mAdapter;public SimpleItemTouchHelperCallback(  ItemTouchHelperAdapter adapter) { mAdapter = adapter;}

然后覆蓋剩下的事件并通知Adapter:

@Overridepublic boolean onMove(RecyclerView recyclerView,   RecyclerView.ViewHolder viewHolder,   RecyclerView.ViewHolder target) { mAdapter.onItemMove(viewHolder.getAdapterPosition(),    target.getAdapterPosition()); return true;}@Overridepublic void onSwiped(RecyclerView.ViewHolder viewHolder,   int direction) { mAdapter.onItemDismiss(viewHolder.getAdapterPosition());}

這個Callback應該看起來像這樣:

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()); }}

當Callback準備好之后, 我們創建ItemTouchHelper并調用attachToRecyclerView(RecyclerView)方法:

ItemTouchHelper.Callback callback =  new SimpleItemTouchHelperCallback(adapter);ItemTouchHelper touchHelper = new ItemTouchHelper(callback);touchHelper.attachToRecyclerView(recyclerView);

當你運行的時候, 結果應該看起來像這樣:

總結

這是一個ItemTouchHelper極簡單的實現. 但是我們應該清楚, 在RecyclerView上面實現基本的"拖放"和"滑動刪除", 使用第三方和庫是完全沒有必要的.

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 黑河市| 裕民县| 古交市| 遂平县| 永安市| 迁西县| 石屏县| 彰化市| 哈巴河县| 濮阳市| 宽城| 开江县| 合作市| 安多县| 崇州市| 三明市| 瑞丽市| 安阳县| 外汇| 长乐市| 平湖市| 张家界市| 大宁县| 永顺县| 开江县| 灵川县| 金川县| 冷水江市| 衡山县| 湘潭市| 阿鲁科尔沁旗| 金寨县| 绥化市| 弥勒县| 连江县| 惠安县| 安福县| 太湖县| 远安县| 平罗县| 梁平县|