0

I am working on an android app in which I need to have the functionality of changing the order of cards in RecyclerView by drag and drop. Till now I am able to move cards by dragging them. But I am facing one issue, that is when I drag card below it goes behind the card that is below that card while when I move it up it comes ahead of the card above it as can be seen in the image.

enter image description here

I want that card that I am dragging to be always above other cards. So I tried providing extra elevation to the card that I am moving but still, the result is same. Below are snippets of code that are related to this part of my app. App's minimum SDK is 22

card layout XML file. (file is too large to show here so this is an outline of it. Compressed views don't have any elevation attributes.)

enter image description here

The content of onTouch listener.

        moveButton.setOnTouchListener({v: View?, event: MotionEvent? ->
    if (v == null || event == null) return@setOnTouchListener true
    when (event.action){
        MotionEvent.ACTION_UP -> {
            v.performClick()
            pressUP(v,event)
        }
        MotionEvent.ACTION_DOWN -> {
            pressDown(v,event)
        }
        MotionEvent.ACTION_MOVE -> {
            pressMove(v,event)
        }
        else -> {
            null
        }
    }
    return@setOnTouchListener true
})

private fun pressDown(imageButton: View, event: MotionEvent){
    openedLayoutManagerLocal?.closeOpenedLayout()
    fragment.mLayoutManager?.setScrollEnabled(false)
    originalDelta = itemView.y
    _yDelta = itemView.y - event.rawY
    itemView.elevateLayoutLocal.elevation = elevation + 10 // as all layouts are by default elevated by 5
}

private fun pressUP(imageButton: View, event: MotionEvent){
    fragment.mLayoutManager?.setScrollEnabled(true)
    val a = itemView.animate()
            .y(originalDelta)
            .setDuration(100)
    a.setListener(object : Animator.AnimatorListener{
        override fun onAnimationEnd(animation: Animator?) {
            itemView.elevateLayoutLocal.elevation = elevation + 5
        }

        override fun onAnimationStart(animation: Animator?) {

        }

        override fun onAnimationRepeat(animation: Animator?) {

        }

        override fun onAnimationCancel(animation: Animator?) {
            itemView.elevateLayoutLocal.elevation = elevation + 5
        }
    })
    a.start()

}

private fun pressMove(imageButton: View, event: MotionEvent){
    itemView.animate()
            .y(event.rawY + _yDelta)
            .setDuration(0)
            .start()
}

So is there anything wrong with how I am assigning elevation? I will also like to know if there is some other way to make this effect. Thank you in advance.

Community
  • 1
  • 1
Mandar Sadye
  • 689
  • 2
  • 9
  • 30
  • Try to use "andorid:elevation" for the cards and use an state animator, which increases the elevation via tranzlateZ in an animation like: https://stackoverflow.com/a/43758592/2139738 , Another thing is, use the implemented way to drag recycler view items, explained here: https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-b9456d2b1aaf – Kenny Seyffarth Jun 24 '18 at 13:15
  • With this suggestions, you should be able to move your cards correctly ;) – Kenny Seyffarth Jun 24 '18 at 13:15

0 Answers0