I had problems with implementation via ItemTouchHelper, then I found in stackover, this is the solution Drag and Drop between two RecyclerView Rewrote it on kotlin for testing to figure out how to do in my app - here's my github - https://github.com/Avdors/RecyclerDragAndDrop here's the java original, 6 years old - https://github.com/jkozh/DragDropTwoRecyclerViews But can't solve the problem, drag and drop works but only if I drag an item from the top to another item. If I drag into an empty space or into an empty recyclerview, it doesn't work, and I want the item to be moved to the end of the list. Can anyone tell me how to solve this?
I tried to look at other DragEvent, DragEvent.ACTION_DRAG_EXITED works when releasing an item, but it works when releasing and taking an object to drag, 4 times in a row. And if you don't put an element above another element ACTION_DROP doesn't work, in the project Log to see where it starts. I thought as an option to fill recycler with invisible elements, but it seems there should be a simpler solution. Here's the code for the basic implementation:`class DragListener(private val listener: Listener) : View.OnDragListener {
private var isDropped = false
override fun onDrag(v: View, event: DragEvent): Boolean {
when (event.action) {
// DragEvent.ACTION_DROP,
// DragEvent.ACTION_DRAG_EXITED
DragEvent.ACTION_DROP -> {
Log.d("MyLog", "ACTION_DROP")
isDropped = true
var positionTarget: Int
val viewSource = event.localState as? View
val viewId = v.id
val flItem = R.id.frame_layout_item
val tvEmptyListTop = R.id.tvEmptyListTop
val tvEmptyListBottom = R.id.tvEmptyListBottom
val rvTop = R.id.rvTop
val rvBottom = R.id.rvBottom
Log.d("MyLog", "viewId $viewId")
when (viewId) {
flItem, tvEmptyListTop, tvEmptyListBottom, rvTop, rvBottom -> {
Log.d("MyLog", "flItem, tvEmptyListTop, tvEmptyListBottom, rvTop, rvBottom")
val target: RecyclerView = when (viewId) {
tvEmptyListTop, rvTop -> v.rootView.findViewById(rvTop)
tvEmptyListBottom, rvBottom -> v.rootView.findViewById(rvBottom)
else -> v.parent as RecyclerView
}
positionTarget = v.tag as Int
Log.d("MyLog", "positionTarget = $positionTarget")
Log.d("MyLog", "viewSource $viewSource")
if (viewSource != null) {
val source = viewSource.parent as RecyclerView
val adapterSource = source.adapter as ListAdapter
val positionSource = viewSource.tag as Int
Log.d("MyLog", "positionSource $positionSource")
val list = adapterSource.getList()[positionSource]
val listSource = adapterSource.getList().toMutableList()
listSource.removeAt(positionSource)
adapterSource.updateList(listSource)
adapterSource.notifyDataSetChanged()
val adapterTarget = target.adapter as ListAdapter
Log.d("MyLog", "target $target")
val customListTarget = adapterTarget.getList().toMutableList()
Log.d("MyLog", "customListTarget $customListTarget")
if (positionTarget < 0) {
customListTarget.add(list)
// customListTarget.add(positionTarget, list)
} else {
customListTarget.add(positionTarget, list)
}
adapterTarget?.updateList(customListTarget)
adapterTarget?.notifyDataSetChanged()
}
}
}
}
DragEvent.ACTION_DRAG_EXITED -> {
Log.d("MyLog", "Enter ACTION_DRAG_EXITED")
}
}
if (!isDropped && event.localState != null) {
(event.localState as? View)?.visibility = View.VISIBLE
}
return true
}
}`
Everything worked out, I need to put listeners for recyclerview. otherwise DragEvent.ACTION_DROP doesn't work when releasing an element on another recyclerview. I have updated the code in Github, maybe someone will need a more recent working example in kotlin. https://github.com/Avdors/RecyclerDragAndDrop In my activity, I add:
and
here's all MainActivity:
}