1

I have a RecyclerView with an header on top( namely a title, a TextView that describe the content of the RecyclerView)

Now I combined two different ViewHolders with some logic into the Adapter to obtain this effect, but I have an unexpected result.

The recyclerView hava to have dividers, but I have a line I want to eliminate between the TextViewand the first Item of the `RecyclerView:

In other words I need to eliminate only the top divider of the RecyclerView, the first item, because I want that between the TextView on top and the list below there is not separation, the other items instead I expect they are separated as I obtained

This post shows how to eliminate the last row divider of a RV, but i need the first top line and I have no idea how I can adapt this snippet to my use case, or if I should create a new class.

Drocchio
  • 383
  • 4
  • 21

1 Answers1

4

In the RecyclerView.ItemDecoration I want to identify the first view in the RecyclerView and not draw a decoration for it. I will also want to not reserve any space for the decoration since it is not drawn. This necessitates an override of getItemOffsets().

Here is some code that applies a decoration to the bottom of all RecyclerView items except the first and the last.

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

    public DividerItemDecorator(Drawable divider) {  
        mDivider = divider;  
    }  

    @Override  
  public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {  
        int pos = parent.getChildAdapterPosition(view);  
        if (pos != 0 &&  
            pos != parent.getLayoutManager().getItemCount() - 1) {  
            outRect.bottom = mDivider.getIntrinsicHeight();  
        }  
    }  

    @Override  
  public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {  
        int dividerLeft = parent.getPaddingLeft();  
        int dividerRight = parent.getWidth() - parent.getPaddingRight();  

        int childCount = parent.getChildCount();  
        for (int i = 0; i < childCount; i++) {  
            View child = parent.getChildAt(i);  

            int pos = parent.getChildAdapterPosition(child);  
            if (pos != 0 &&  
                pos != parent.getLayoutManager().getItemCount() - 1) {  

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

                int dividerTop = child.getBottom() + params.bottomMargin;  
                int dividerBottom = dividerTop + mDivider.getIntrinsicHeight();  
                mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom);  
                mDivider.draw(canvas);  
            }  
        }  
    }  
}

Here is what this looks like. I have exaggerated the dividers so they would stand out.

enter image description here

Cheticamp
  • 61,413
  • 10
  • 78
  • 131
  • Thanks but can I call `DividerItemDecorator` from the `Adapter`? I change in real time the state of three different recycler view into the adapter. So I cannot call `Recyclerview.ItemDecoration` from the Activity View. Anyway I had to specify this before. I am going to accept your reply – Drocchio Jan 12 '19 at 20:51
  • @Drocchio You can set the `ItemDecoration` in the adapter. Probably the best place would be in `onAttachedToRecyclerView()`. That callback is invoked before any layout. – Cheticamp Jan 12 '19 at 22:38
  • @Cheticamp is there a way to add a divider before the first item? – Gauri Gadkari May 20 '22 at 00:50