Written by Marcin Kitowicz
Android developer
Published June 26, 2017

Swipe to delete done easier than you thought

Recently I had to implement swipe to delete function. As is often the case, sometimes you need to enhance the functionality in the application using 3rd party libraries. This is what happened.

Swipe to delete

It’s nothing wrong with using 3rd party libraries. Here are some advantages that quickly came to my mind:

  • often such code has good quality,
  • you can save some time,
  • in general, reinventing the wheel is not a good idea.

There is also the other side of the coin:

  • open source is cool, but when you find a bug in the library, you need to fix it by yourself,
  • customisation might be cumbersome,
  • you have to accept library’s dependencies, even if you’re not using them,

Last but not least, in my opinion, using a ready-made solution prevents us from discovering and learning new stuff.

It was similar in my case. Ability to delete rows from RecyclerView’s list was all that I needed. A quick look at the documentation and I realised that I could accomplish it very easily!

ItemTouchHelper.SimpleCallback

Using this class, we can detect and react to events related to:

  • swipe items (from right, left or both sides);
  • move items (up, down or both).

Let’s create our implementation based on SimpleCallback (to make code cleaner I placed only the most important fragments, check the full code here):

abstract class SwipeToDeleteCallback(context: Context) : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {

    override fun onMove(...): Boolean {
        return false // We don't want support moving items up/down
    }

    // Let's draw our delete view
    override fun onChildDraw(canvas, recyclerView, viewHolder, ..) {
        val itemView = viewHolder.itemView
        val itemHeight = itemView.bottom - itemView.top

        // Draw the red delete background
        background.color = backgroundColor
        background.setBounds(
                itemView.right + dX.toInt(),
                itemView.top,
                itemView.right,
                itemView.bottom
        )
        background.draw(canvas)

        // Calculate position of delete icon
        val iconTop = itemView.top + (itemHeight - inHeight) / 2
        val iconMargin = (itemHeight - inHeight) / 2
        val iconLeft = itemView.right - iconMargin - inWidth
        val iconRight = itemView.right - iconMargin
        val iconBottom = iconTop + inHeight

        // Draw the delete icon
        icon.setBounds(iconLeft, iconTop, iconRight, iconBottom)
        icon.draw(canvas)
        
        super.onChildDraw(canvas, recyclerView, viewHolder, ...)
    }
}

SimpleCallback’s constructor is using two parameters — which directions you want to support, in our case just swipe from right to left. In onChildDrawmethod, you need to manually calculate and draw the background with an icon (I used ic_delete from the Material icons).

Next thing is to connect Callback with our RecyclerView:

recyclerView.layoutManager = LinearLayoutManager(context)
recyclerView.adapter = SimpleAdapter()

val swipeHandler = object : SwipeToDeleteCallback(context) {
    override fun onSwiped(...) {
        val adapter = recyclerView.adapter as SimpleAdapter
        adapter.removeAt(viewHolder.adapterPosition)
    }
}
val itemTouchHelper = ItemTouchHelper(swipeHandler)
itemTouchHelper.attachToRecyclerView(recyclerView)

Finally, the last thing you need is ability to delete item in an adapter. You can achieve this by doing that:

class SimpleAdapter : RecyclerView.Adapter<SimpleAdapter.VH>() {http://www.schibsted.pl/wp-admin/post.php?post=12104&action=edit#

    // ...
    
    fun removeAt(position: Int) {
        items.removeAt(position)
        notifyItemRemoved(position)
    }
}

Swipe to remove

That’s it! As you can see, the advantages of using 3-rd party libraries overcome some of the drawbacks. You can spend the time saved thanks to using them on researching new ones, and further simplify some tasks.

Links:

Written by Marcin Kitowicz
Android developer
Published June 26, 2017