7

I'm using the RecyclerView.ItemDecoration class to create dividers in the list, but I want to hide the divider for the last item in the list. Is this possible without having to implement the dividers myself?

fobbymaster
  • 1,406
  • 3
  • 14
  • 22

3 Answers3

4

You can try this,

public class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration {
    private Drawable mDivider;

    public SimpleDividerItemDecoration(Context context) {
        mDivider = ContextCompat.getDrawable(context, R.drawable.line_divider);
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        int left = parent.getPaddingLeft();
        int right = parent.getWidth() - parent.getPaddingRight();

        int childCount = parent.getAdapter().getItemCount();
        for (int i = 0; i < childCount; i++) {

            if (i == (childCount - 1)) {
                continue;
            }

            View child = parent.getChildAt(i);

            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

            int top = child.getBottom() + params.bottomMargin;
            int bottom = top + mDivider.getIntrinsicHeight();

            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }
}

line_divider.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <size
        android:width="1dp"
        android:height="1dp" />
    <solid android:color="#F5F5F5" />
</shape>
Taslim Oseni
  • 6,086
  • 10
  • 44
  • 69
Muthukrishnan Rajendran
  • 11,122
  • 3
  • 31
  • 41
  • This did not work, unfortunately. Actually, I'm getting a weird off by one issue. This seems to be the correct way to do it, but I need to figure out the other bugs in my code. Thanks – fobbymaster Jun 22 '17 at 20:23
  • 3
    This is incorrect answer. `childCount - 1` will give you index of the last **visible** child. The correct comparison would be: `parent.getChildAdapterPosition(child) == parent.getAdapter().getItemCount() - 1` as stated the answer from @Maxim Turaev – Stanislav Dec 01 '17 at 17:37
  • 1
    @Stanislav is right, this does not work at all. When scrolling through items, the `parent.getChildCount()` will grow as the list is filled since it represents the current number of _displayed_ items; hence the item decoration for the intended last item will instead be applied to every item while scrolling down the list and growing the child count. I suggested an edit to the answer using `getAdapter().getItemCount()` which solves the problem. – JHH Mar 19 '18 at 08:11
  • Response from Stanislav did the trick for me – Mattia Ruggiero Jul 13 '22 at 13:11
4

Try Kotlin version, inspired by @Muthukrishnan Rajendran

CommentDetailItemDecoration.kt

class CommentDetailItemDecoration(
        context: Context
) : RecyclerView.ItemDecoration() {
    val drawable: Drawable = ContextCompat.getDrawable(context, R.drawable.ft_item_divider)!!

    override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        val left = parent.paddingLeft
        val right = parent.width - parent.paddingRight

        val childCount = parent.adapter!!.itemCount
        for (i in 0 until childCount - 1) {
            val child = parent.getChildAt(i)
            if (child != null) {
                val params = child.layoutParams as RecyclerView.LayoutParams
                val top = child.bottom + params.bottomMargin
                val bottom = top + drawable.intrinsicHeight
                drawable.setBounds(left, top, right, bottom)
                drawable.draw(c)
            }
        }
    }
}

ft_item_divider.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <size
        android:width="1dp"
        android:height="1dp" />
    <solid android:color="@color/grey_97" />

</shape>
mariozawa
  • 1,504
  • 1
  • 11
  • 14
Felix J
  • 101
  • 1
  • 6
3

[UPDATE]
You can simply copy or extend DividerItemDecoration class and change its drawing behaviour by modifying

for (int i = 0; i < childCount; i++) to for (int i = 0; i < childCount - 1; i++)

Maksim Turaev
  • 4,115
  • 1
  • 29
  • 42