U wan
U wan

Reputation: 61

RecyclerView Drag-and-Drop Item Disappears While Moving - Android

I have a RecyclerView where I've implemented drag-and-drop functionality using ItemTouchHelper. The issue is that when I drag an item, it sometimes disappears from the screen while moving(dissapears like moving outside the box). The strange part is that I can still see it being dragged, but at some point, it goes off the screen or becomes invisible.

video link : [1]: https://drive.google.com/file/d/1o7ZgcFUf-D8LVMAGI-E9mOt51g66u6wf/view?usp=sharing

override fun onItemMove(fromPosition: Int, toPosition: Int): Boolean {
    if (fromPosition < toPosition) {
        for (i in fromPosition until toPosition) {
            Collections.swap(cities, i, i + 1)
        }
    } else {
        for (i in fromPosition until toPosition) {
            Collections.swap(cities, i, i - 1)
        }
    }
    notifyItemMoved(fromPosition, toPosition)
    return true
}

second

  class DragAndDropCallback(
 private val adapter: PlanRouteAdapter
  ) : ItemTouchHelper.Callback() {
  override fun getMovementFlags(
    recyclerView: RecyclerView,
    viewHolder: RecyclerView.ViewHolder
 ): Int {
    val dragFlags = if (viewHolder.bindingAdapterPosition  in 1 until 
 adapter.itemCount - 1) {
        ItemTouchHelper.UP or ItemTouchHelper.DOWN
    } else {
        0
    }
    val swipeFlags = 0
     return makeMovementFlags(dragFlags, swipeFlags)
 }
    /* val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
    val swipeFlags = 0
   val itemCount = adapter.itemCount
   val currentPosition = viewHolder.adapterPosition
   if (currentPosition == 0 || currentPosition == itemCount - 1) {
     return makeMovementFlags(0, swipeFlags)
   }

  return makeMovementFlags(dragFlags, swipeFlags)*/
  override fun onMove(
    recyclerView: RecyclerView,
    viewHolder: RecyclerView.ViewHolder,
    target: RecyclerView.ViewHolder
    ): Boolean {
    val fromPosition = viewHolder.bindingAdapterPosition
    val toPosition = target.bindingAdapterPosition

    if (toPosition == 0 || toPosition == adapter.itemCount - 1) {
        return false
    }
    return adapter.onItemMove(fromPosition, toPosition)
  }
  override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: 
  Int) {
    if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
        viewHolder?.itemView?.setBackgroundColor(Color.WHITE)
    }
    super.onSelectedChanged(viewHolder, actionState)
 }

 override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
 }

 override fun isLongPressDragEnabled(): Boolean {
    return true
 }

 override fun isItemViewSwipeEnabled(): Boolean {
    return true
 }
 }

Upvotes: 1

Views: 78

Answers (1)

U wan
U wan

Reputation: 61

i solved this issue by adding this function in my DragAndDropCallback class:

override fun onChildDraw(
    c: Canvas,
    recyclerView: RecyclerView,
    viewHolder: RecyclerView.ViewHolder,
    dX: Float,
    dY: Float,
    actionState: Int,
    isCurrentlyActive: Boolean
) {
    val topY = viewHolder.itemView.top + dY
    val bottomY = topY + viewHolder.itemView.height

    if (topY >= 0 && bottomY <= recyclerView.height) {
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
    }
}

Upvotes: 1

Related Questions