用RecyclerView實現類似支付寶應用圖示拖拽排序以及增刪管理的功能

Joehaivo飛羽 發表於 2021-03-16

1. 效果圖

WeChat_20210315170631.gif

2. 基本的功能

  1. 在非編輯狀態下可以直接點選圖示進行跳轉
  2. 在編輯狀態可以拖拽、新增、刪除操作
  3. 已被新增過的不能再次新增

3. 實現的思路

用兩個RecyclerView實現,同時維護兩個資料來源,上部是常用應用,最多可以放8個;下部是全部應用。

1. 每個應用圖示的狀態用列舉Option表示

// 當前的操作狀態
enum class Option {
    ADD, REMOVE, NONE
}
複製程式碼

2. 在處於編輯狀態時建立ItemTouchHelper物件並attch到RecyclerView上

if (enable) {
    itemTouchHelper.attachToRecyclerView(binding.rvApps)
} 
複製程式碼

其中,在實現ItemTouchHelper.Callback介面的onMove() 函式中,此時表示使用者已經抬手,而圖示位置已經發生了變動,此時將介面上圖示的順序同步回Adapter的資料來源中:

val newData = mutableListOf<Pair<String, Int>>()
commonAppsAdapter.data.forEachIndexed { index, _ ->
    val holder = recyclerView.findViewHolderForAdapterPosition(index) as AppsHolder
    newData.add(Pair(holder.funcUrl, index))
}
for (i in newData) {
     val sameFuncIndex = commonAppsAdapter.data.indexOfFirst { i.first == it.uid }
     Collections.swap(commonAppsAdapter.data, i.second, sameFuncIndex)
}
複製程式碼

3. 當應用圖示從上部被刪除時,需要將其新增到下部,並將其重新設為可新增狀態

commonAppsAdapter.onRemoveBtnClickListener = object : OnRemoveBtnClickListener {
   override fun onClick(view: View, appBean: AppBean) {
       val theSameElementIndex = allAppsAdapter.data.indexOfFirst { it.uid == appBean.uid }
       if (theSameElementIndex < 0) return
       allAppsAdapter.data[theSameElementIndex].option = AppBean.Companion.Option.ADD
       allAppsAdapter.notifyItemChanged(theSameElementIndex)
   }
}
複製程式碼

原始碼請前往Github

PS: 僅為個人工作中經驗總結,並未認真梳理程式碼,僅供參考實現的思路