Skip to content

Drag & drop - animation is broken #1045

Open
@MFlisar

Description

@MFlisar

About this issue

I see the same issue like in the video here: #991 and I do use stable ids in my adapter...

What I see is following

  • I start a drag
  • I stop it => itemTouchDropped is called followed by itemTouchStopDrag (which seems to be intended, although it seems wrong imho)
  • I update my data in itemTouchDropped => this triggers a data update and updates the adapter data which may happen during a running animation...

Problem

  • itemTouchStopDrag stops the drag animation, this means the item appears at its original position again although the back animation move animation is still running
  • ghost views as in the mentioned other issues video

Work around

I delay the the drop data update until the itemTouchStopDrag is called after a drop.

Here's my code:

private val dragCallback = SimpleDragCallback(object : ItemTouchCallback {

        var updatedItems: List<IDataItem>? = null

        override fun itemTouchOnMove(oldPosition: Int, newPosition: Int): Boolean {
            DragDropUtil.onMove(itemAdapter, oldPosition, newPosition)  // change position
            return true
        }

        override fun itemTouchDropped(oldPosition: Int, newPosition: Int) {
            L.d { "Dropped: $oldPosition => $newPosition" }
            if (oldPosition == newPosition) {
                // drag drop to same position starts the selection mode
                select(activity, oldPosition)
            } else {
                val items = itemAdapter.adapterItems.map { it.data }
                items.forEachIndexed { index, item ->
                    item.order = index
                }
                updatedItems = items
            }
        }

        override fun itemTouchStartDrag(viewHolder: RecyclerView.ViewHolder) {
            L.d { "Drag start..." }
        }

        override fun itemTouchStopDrag(viewHolder: RecyclerView.ViewHolder) {
            L.d { "Drag stop..." }
            updatedItems?.let {
                GlobalScope.launch(Dispatchers.IO) {
                    DataManager.update(it)
                }
            }
            updatedItems = null
        }
    }).apply {
        notifyAllDrops = true
        isDragEnabled = true
    }

Question

What's the reason to not delay the itemTouchDropped until after itemTouchStopDrag? This seems unlogical to me...

Details

  •  Used library version 5.7.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions