編輯:關於Android編程
在平時開發應用的時候,經常會遇到列表排序、滑動刪除的需求。如果列表效果采用的是 ListView 的話,需要經過自定義 View 才能實現效果;但是如果采用的是 RecyclerView 的話,系統 API 就已經為我們提供了相應的功能。
接下來,我們就來看一下怎麼用系統 API 來實現排序和刪除的效果。
創建 ItemTouchHelper
創建一個 ItemTouchHelper 對象,然後其調用 attachToRecyclerView 方法:
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)); RecyclerViewAdapter adapter = new RecyclerViewAdapter(); ItemTouchHelper helper = new ItemTouchHelper(new MyItemTouchCallback(adapter)); helper.attachToRecyclerView(recyclerView);
在創建 ItemTouchHelper 對象時候,需要我們傳入一個實現了 ItemTouchHelper.Callback 接口的對象。而排序和刪除的邏輯都封裝在了這個 ItemTouchHelper.Callback 的對象裡面了。
實現 ItemTouchHelper.Callback 接口
創建 MyItemTouchCallback 類,實現 ItemTouchHelper.Callback 接口:
public class MyItemTouchCallback extends ItemTouchHelper.Callback { private final RecyclerViewAdapter adapter; public MyItemTouchCallback(RecyclerViewAdapter adapter) { this.adapter = adapter; } @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { return 0; } @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { return false; } @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { } }
實現 ItemTouchHelper.Callback 接口後有三個方法需要重寫:
重寫方法
我們先來看看 getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) 方法:
@Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { int dragFlag; int swipeFlag; RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); if (layoutManager instanceof GridLayoutManager) { dragFlag = ItemTouchHelper.DOWN | ItemTouchHelper.UP | ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT; swipeFlag = 0; } else { dragFlag = ItemTouchHelper.DOWN | ItemTouchHelper.UP; swipeFlag = ItemTouchHelper.END; } return makeMovementFlags(dragFlag, swipeFlag); }
代碼中根據 layoutManager 分為了兩種情況:
下面就是 onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) 方法:
@Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { int fromPosition = viewHolder.getAdapterPosition(); int toPosition = target.getAdapterPosition(); if (fromPosition < toPosition) { for (int i = fromPosition; i < toPosition; i++) { Collections.swap(adapter.getDataList(), i, i + 1); } } else { for (int i = fromPosition; i > toPosition; i--) { Collections.swap(adapter.getDataList(), i, i - 1); } } recyclerView.getAdapter().notifyItemMoved(fromPosition, toPosition); return true; }
之前說過了,onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) 方法是用戶在拖拽 item 的時候會回調。所以關於列表排序的代碼應該寫在這裡。方法參數中的 viewHolder 代表的是用戶當前拖拽的 item ,而 target 代表的是被用戶拖拽所覆蓋的那個 item 。所以在 onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) 方法中的邏輯就是把 fromPosition 至 toPosition 為止改變它們的位置。
最後就是 onSwiped(RecyclerView.ViewHolder viewHolder, int direction) 方法了:
@Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { int position = viewHolder.getAdapterPosition(); if (direction == ItemTouchHelper.END) { adapter.getDataList().remove(position); adapter.notifyItemRemoved(position); } }
這個方法在用戶進行側滑刪除操作的時候會回調,其中的邏輯就是得到當前用戶進行側滑刪除操作的 item ,然後將其刪除。
到了這裡,大功告成了。那麼來看看效果吧:
效果圖
改善用戶體驗
我們發現還有一些不完美的地方:比如當用戶在拖拽排序的時候,可以改變當前拖拽 item 的透明度,這樣就可以和其他 item 區分開來了。那麼,我們需要去重寫 onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) 方法:
@Override public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { super.onSelectedChanged(viewHolder, actionState); if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) { viewHolder.itemView.setBackgroundColor(Color.BLUE); } }
相對應地,當用戶手指從拖拽 item 中抬起的時候,我們需要把 item 的透明度復原。需要我們重寫 clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) 方法:
@Override public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { super.clearView(recyclerView, viewHolder); viewHolder.itemView.setBackgroundColor(0); }
好了,來看看改進之後的效果:
改進效果圖
源碼下載:TestRV.rar
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。
如果說評價一下哪個圖片開源庫最被廣泛使用的話,我想應該可以說是Universal-Image-Loader,在主流的應用中如果你隨便去反編譯幾個,基本都能看到他的身影,它
菜單包括選項菜單(OptionMenu)、上下文菜單(ContextMenu)、子菜單(SubMenu). 創建子菜單(SubMenu)的步驟: 1、重寫Activity
第二十章、適配器模式 適配器模式是結構型設計模式之一,它在我們的開發中使用率極高,比如ListView、GridView以及RecyclerView都需要使用Adapte
Handler的作用一般是子線程向主線程中傳遞消息,用來主線程處理和UI相關的東西。為什麼要在子線程中用呢,因為如果主線程處理了過多耗時的東西,可能會導致假死,所以一般都