Search code examples
androidandroid-recyclerviewitem-decoration

RecyclerView: Adding bottom spacing for last item with a custom ItemDecoration doesn't work well with DividerItemDecoration and ItemTouchHelper


I am adding a space below the last item in the RecyclerView using this popular and efficient solution:

class ListMarginDecorator(
        private val left: Int = 0,
        private val top: Int = 0,
        private val right: Int = 0,
        private val bottom: Int = 0,
) : RecyclerView.ItemDecoration() {
    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
        super.getItemOffsets(outRect, view, parent, state)
        val position = parent.getChildAdapterPosition(view)

        outRect.left = left
        outRect.top = if (position == 0) top else 0
        outRect.right = right
        outRect.bottom = if (position == state.itemCount - 1) bottom else 0
    }
}

I also add item dividers using DividerItemDecoration, and enable drag-to-reorder by implementing ItemTouchHelper.

Here is how I use these ItemDecorators in the fragment class:

binding.recyclerView.addItemDecoration(
    DividerItemDecoration(
            binding.rvCurrencies.context,
            DividerItemDecoration.VERTICAL
    )
)

binding.recyclerView.addItemDecoration(
    ListMarginDecorator(
        bottom = resources.getDimensionPixelSize(R.dimen.list_last_item_bottom_margin) // = 88dp
    )
)

I see two issues with this approach to space under the last item though.

The first is that ListMarginDecorator seems to be applying padding, not margin, so the bottom divider line for the last item in the list is drawn below the spacing that is applied to that last item.

Divider issue

The second issue is that I can no longer drag an item in the list to the bottom-most position.

Drag to bottom issue

When I comment out the line adding the ListMarginDecorator though, both of these work as expected:

Works

Is there any other way to efficiently add a space under the last item, without running into these issues?


Solution

  • If you want space after the last item, why don't just use

    rvCurrencies.setPadding(0, 0, 0, 100)
    rvCurrencies.clipToPadding = false
    

    or in XML

    android:paddingBottom="100dp"
    android:clipToPadding="false"
    

    in this way, your all two problems will be sorted out.