I have show a list of Items with RecyclerView and I have items of different types (headers and items), like the following
Header 1
Item 1
Item 2
Header 2
Item 3
Item 4
Item 5
Item 6
Header 3
Item 7
....
I would like to limit swapping the position of Items inside their section Headers. So for example, Item 4 can be swapped with Item 3, Item 5 and Item 6 but not go outside it's section boundaries. I'm using ItemTouchHelper
to implement the swap on drag mechanism as suggested here https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-b9456d2b1aaf and https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-6a6f0c422efd
I overloaded the canDropOver
method which helps if you want to swap for example Item 4 and Header 2 but not in preventing me in dragging the Item till Header 1. Any suggestions?
Once you've got canDropOver
set, the last piece of the puzzle is to override onChildDraw
and clamp the dY
value (assuming a vertical list -- clamp the dX
value if using a horizontal list) whenever a ViewHolder
is being dragged toward an adjacent ViewHolder
it can't drop over.
For example:
override fun onChildDraw(
c: Canvas,
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
dX: Float,
dY: Float,
actionState: Int,
isCurrentlyActive: Boolean
) {
val previousViewHolder = recyclerView.findViewHolderForAdapterPosition(viewHolder.bindingAdapterPosition - 1)
val nextViewHolder = recyclerView.findViewHolderForAdapterPosition(viewHolder.bindingAdapterPosition + 1)
val isDraggingUpward = dY < 0
val isDraggingDownward = dY > 0
val isDraggingIntoUndraggableArea =
(isDraggingUpward && previousViewHolder != null && !canDropOver(recyclerView, viewHolder, previousViewHolder))
|| (isDraggingDownward && nextViewHolder != null && !canDropOver(recyclerView, viewHolder, nextViewHolder))
val newDy = if (isDraggingIntoUndraggableArea) {
0f // Clamp
} else {
dY
}
super.onChildDraw(c, recyclerView, viewHolder, dX, newDy, actionState, isCurrentlyActive)
}
I've also got a repository you can refer to which has a full app example: https://github.com/nihk/ClampedItemTouchHelper