Reputation: 322
I need to somehow notify RecyclerView
when I drag and drop an item from another RecyclerView
onto it.
RecyclerView
with blue items is in one fragment and RecyclerView
with red items is in another fragment.
I also tried using ItemTouchHelper but it's onMove() method from ItemTouchHelper.Callback is not called while moving with item outside
from RecyclerView
.
private class CustomItemTouchCallback extends Callback {
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
return makeMovementFlags(UP|DOWN|START|END, 0);
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
android.util.Log.d(TAG, "Move item from:" + viewHolder.getAdapterPosition() + " to: " + target.getAdapterPosition());
return true;
}
@Override
public void onMoved(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, int fromPos, RecyclerView.ViewHolder target, int toPos, int x, int y) {
android.util.Log.d(TAG, "Moved item from:" + fromPos + " to: " + toPos + " x: " + x + " y: " + y);
super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y);
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
}
@Override
public boolean isLongPressDragEnabled() {
return true;
}
@Override
public boolean isItemViewSwipeEnabled() {
return false;
}
}
I also find this question, but it doesn't solve my problem.
Upvotes: 24
Views: 4530
Reputation: 21
I have done it by using ItemTouchHelper and OnItemTouchListener
var selectedViewHolder: RecyclerView.ViewHolder? = null
val itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(
ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.ACTION_STATE_DRAG, 0
) {
override fun onMove(
recyclerView: RecyclerView,
source: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
val sourcePosition = source.adapterPosition
val targetPosition = target.adapterPosition
if (selectedViewHolder == null) {
selectedViewHolder =
recyclerView.findViewHolderForAdapterPosition(sourcePosition)
Collections.swap(customerList, sourcePosition, targetPosition)
custAdapter.notifyItemMoved(sourcePosition, targetPosition)
return true
}
return false
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
}
})
itemTouchHelper.attachToRecyclerView(binding.rvCustomerList)
binding.rvCustomerList.addOnItemTouchListener(object : RecyclerView.OnItemTouchListener {
val gestureDetector = GestureDetector(
requireContext(),
object : GestureDetector.SimpleOnGestureListener() {
override fun onLongPress(e: MotionEvent) {
val childView = binding.rvCustomerList.findChildViewUnder(e!!.x,e!!.y)
motionEvent = MotionEvent.obtain(e)
when (e?.action) {
MotionEvent.ACTION_DOWN -> {
val data = ClipData.newPlainText("", "")
val shadowBuilder = DragShadowBuilder(
childView
)
childView!!.startDrag(data, shadowBuilder, view, 0)
motionEvent = MotionEvent.obtain(e)
}
MotionEvent.ACTION_MOVE -> {
childView!!.x = e.x
childView!!.y = e.y
}
else -> {
}
}
}
})
override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean {
gestureDetector.onTouchEvent(e)
return false
}
override fun onTouchEvent(rv: RecyclerView, e: MotionEvent) {}
override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {}
})
In this rvCustomerList is the recyclerview. Now I can move the selected item from recyclrview anywhere in the screen.
Hope this is helpful.
Upvotes: 0
Reputation: 17788
Old question, but no answer yet, so I provide a short one...
For dragging something from one view to another you can use the DragShadowBuilder
. The ItemTouchHelper
is only meant for moving items within the RecyclerView
, you need a custom implementation for what you want.
Check out this documentation: https://developer.android.com/guide/topics/ui/drag-drop (so yes, for what you want you should is this classic drag&drop framework as you called it)
It shows you how to create the shadow, how to move it (done automatically) and how to react to the drag event in the second view.
The workflow is following:
RecyclerView
1 (it's a copy of the item, drawn over the app)View.OnDragListener
on the second RecyclerView
and handle the events (e.g. add the data in the second RecyclerView
if the user drops it over it and remove it from the first RecyclerView
)With the help of DragShadowBuilder
you can find tutorials on this, like e.g. the one here: http://www.vogella.com/tutorials/AndroidDragAndDrop/article.html
Upvotes: 3