九宮格圖片佈局,長按直接拖拽圖片,長按時顯示底部刪除佈局,拖拽到刪除佈局處鬆手可刪除佈局,最後添加按鈕不可拖拽,基於 BaseQuickAdapter 基礎上實現 BaseQuickAdapter 確實很好用,簡化我們的實現代碼,它本身也集成了一套拖拽實現,不過目前無法完美的滿足上面的需求,需要做一 ...
九宮格圖片佈局,長按直接拖拽圖片,長按時顯示底部刪除佈局,拖拽到刪除佈局處鬆手可刪除佈局,最後添加按鈕不可拖拽,基於 BaseQuickAdapter 基礎上實現
BaseQuickAdapter 確實很好用,簡化我們的實現代碼,它本身也集成了一套拖拽實現,不過目前無法完美的滿足上面的需求,需要做一些修改
1、首先自定義好九宮格佈局,末尾是一個 + 號,這個加號無法拖拽,這裡 + 號最好是用圖片,更方便
2、在 adapter 中重寫 addDraggableModule 方法,這裡我直接自定義了自己的 DraggableModule ,因為我需要替換預設的監聽事件,達到我自己的目的
核心邏輯就集中在 PhotoDraggableModule 中,否則自帶的拖拽沒發監聽拖拽的距離,不好計算是否拖拽到了底部
源碼中在 module 初始化的時候就已經把監聽初始化了,所以在不替換的情況下,很難達到自己的需求
其實就是 DragAndSwipeCallback ,自己定義有點麻煩,還不如不用這套拖拽封裝了,所以為了簡化,只能繼續用它,在它的基礎上計算自己的拖拽距離就行了
直接在 module 中的 init 方法里 重新創建監聽,去替換原有的 callback,這樣就方便自己獲取數據操作了
init { itemTouchHelperCallback = object : DragAndSwipeCallback(this) { override fun onChildDraw( c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean ) { super.onChildDraw( c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive ) if (callBack == null) return if (isCurrentlyActive) { viewHolder.itemView.visibility = View.VISIBLE if (dY.toInt() == 0) { isDel = false callBack?.touchStart() } else if (dY > 0) { //拖到指定區域 val bottom = (recyclerView.parent.parent as View).bottom + dY val bottomY = bottom - (recyclerView.bottom - viewHolder.itemView.bottom) - (scrollView?.scrollY ?: 0) //是否在刪除區域 isDel = bottomY >= bottomDelTopY callBack?.touchMove(isDel) } } else { val delPosition = if (isDel) viewHolder.layoutPosition else null //鬆開先隱藏,預防鬆開後item回到列表在執行刪除動畫 viewHolder.itemView.visibility = if (isDel) View.INVISIBLE else View.VISIBLE callBack?.touchUp(delPosition) isDel = false } } @SuppressLint("NotifyDataSetChanged") override fun clearView( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder ) { super.clearView(recyclerView, viewHolder) viewHolder.itemView.visibility = View.VISIBLE //等待佈局操作結束執行刷新,避免下方異常 //Cannot call this method while RecyclerView is computing a layout or scroll viewHolder.itemView.post { baseQuickAdapter.notifyDataSetChanged() } } } itemTouchHelper = ItemTouchHelper(itemTouchHelperCallback) }
3、計算拖拽距離
如果沒有被 scrollView 嵌套,直接通過拖拽的距離就能判斷是否到底部了,但是一般情況下都需要你可滑動,就會需要嵌套一層 scrollVIew
根據上面代碼看出,其實就是需要獲取 scrollView 的滾動距離,從中得出你拖拽的距離是否到底部了,這裡用 isDel 來控制執行次數,否則會重覆調用多次
4、最後在回調監聽中處理拖拽的動畫和刪除操作