I'm working on my time management app Mission Control, built in Kotlin Android studio. I have an option to create a list of tasks using recyclerview and I implemented drag and drop to enable replacing the order, which works perfect if I have only a few items, in the attached gif I show how it gets very hard to drag and drop when there are more items in the list.. Anyone has any clue on how to solve this behavior? I tried using different drag and drop functions but nothing seems to solve it.
In case you want to give the app a try it's free here: link
My code:
//Implementation of drag and drop - Vertical in a task list combined with
// the implementation of the swipe
//Devider between items
val dividerItemDecoration =
DividerItemDecoration(this, DividerItemDecoration.VERTICAL)
// Remove all existing item decorations - important!
for (i in rvTaskList?.itemDecorationCount!! - 1 downTo 0) {
rvTaskList?.removeItemDecorationAt(i)
}
rvTaskList?.addItemDecoration(dividerItemDecoration)
//Resetting drag positions
var mPositionDraggedFrom = -1
var mPositionDraggedTo = -1
//Remove former helpers - important!
itemTouchHelper?.attachToRecyclerView(null)
val helper = ItemTouchHelper(object : SwipeHelper(rvTaskList) {
override fun getMovementFlags(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder
): Int {
//Decides the touch direction - swipe or drag to replace
return makeMovementFlags(
ItemTouchHelper.UP or ItemTouchHelper.DOWN,
ItemTouchHelper.LEFT
)
}
override fun instantiateUnderlayButton(position: Int): List<UnderlayButton> {
//Creates the swiped buttons
var buttons = listOf<UnderlayButton>()
val deleteButton = deleteButton(position)
val editButton = editButton(position)
buttons = listOf(deleteButton, editButton)
return buttons
}
override fun onMove(
recyclerView: RecyclerView,
dragged: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
//Moving items in the rv
val draggedPosition = dragged.adapterPosition
val targetPosition = target.adapterPosition
if (mPositionDraggedFrom == -1) {
mPositionDraggedFrom = draggedPosition
}
mPositionDraggedTo = targetPosition
//Changing the location in a list from the dragged tp target
Collections.swap(
mPlanDetails.dayPlanList[mDayPlanPosition].tasks,
draggedPosition,
targetPosition
)
taskAdapter.notifyItemMoved(draggedPosition, targetPosition)
return false
}
override fun clearView(
//Called once the drag and drop is over
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder
) {
super.clearView(recyclerView, viewHolder)
if (mPositionDraggedFrom != -1 && mPositionDraggedTo != -1 &&
mPositionDraggedFrom != mPositionDraggedTo
) {
updateTasksInDayPlan(
mDayPlanPosition, mPlanDetails.dayPlanList[mDayPlanPosition].tasks
)
}
}
})
//Attach the helper
itemTouchHelper = helper
itemTouchHelper?.attachToRecyclerView(rvTaskList)
onMove method should return true according to the documentation:
"If this method returns true, ItemTouchHelper assumes viewHolder has been moved to the adapter position of target ViewHolder"