Como adicionar divisores e espaços entre itens em Reciclerview?

Este é um exemplo de como poderia ter sido feito anteriormente na classe ListView, usando o divisor edivisorheight :

<ListView
    android:id="@+id/activity_home_list_view"
    android:layout_width="match_parent" 
    android:layout_height="match_parent"
    android:divider="@android:color/transparent"
    android:dividerHeight="8dp"/>
No entanto, não vejo essa possibilidade na turma.

<android.support.v7.widget.RecyclerView
    android:id="@+id/activity_home_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="vertical"/>

nesse caso, é correcto definir margens e / ou adicionar uma vista de divisores personalizada directamente à disposição de um item da lista ou existe uma forma melhor de atingir o meu objectivo?

Author: vuhung3990, 2014-07-08

30 answers

Actualização De Outubro De 2016

A versão 25.0.0 da biblioteca de Suporte do Android introduziu DividerItemDecoration classe:

A separação é uma área de Reciclagem.Itemdecoração que pode ser usado como um divisor entre itens de um LinearLayoutManager. Suporta orientações horizontais e verticais.

Utilização:

DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
    layoutManager.getOrientation());
recyclerView.addItemDecoration(dividerItemDecoration);

Resposta Anterior

Algumas respostas usam métodos que desde então se tornaram desacreditado,ou não dar uma solução completa, então eu tentei fazer um breve, UP-UP-up-up-up.

Ao contrário de ListView, a classe RecyclerView não tem parâmetros relacionados com divisores. Em vez disso, você precisa estender ItemDecoration, classe interna de a RecyclerView:

Uma Itemdecoração permite à aplicação adicionar um deslocamento de desenho e disposição especial às vistas de itens específicas do conjunto de dados do adaptador. Isto pode ser útil para os separadores de desenho entre itens, destaques, agrupamento visual limites e muito mais.

Todas as decisões são desenhadas pela ordem em que foram acrescentadas, antes da vista do item [em onDraw ()] e depois dos itens [em onDrawOver (Canvas, Reciclerview, Reciclerview.Estado).

Espaço Vertical ItemDecoration

Extender ItemDecoration, adicionar um construtor personalizado que toma a altura do espaço como um parâmetro e sobrepor getItemOffsets() método:

public class VerticalSpaceItemDecoration extends RecyclerView.ItemDecoration {

    private final int verticalSpaceHeight;

    public VerticalSpaceItemDecoration(int verticalSpaceHeight) {
        this.verticalSpaceHeight = verticalSpaceHeight;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
            RecyclerView.State state) {
        outRect.bottom = verticalSpaceHeight;
    }
}

Se não quiser inserir espaço por baixo do último item, adicione o seguinte condição:

if (parent.getChildAdapterPosition(view) != parent.getAdapter().getItemCount() - 1) {
            outRect.bottom = verticalSpaceHeight;
}
Nota: também pode modificar outRect.top, outRect.left e outRect.right propriedades para o efeito desejado.

Divisor ItemDecoration

Extender ItemDecoration e anular onDraw() método:

public class DividerItemDecoration extends RecyclerView.ItemDecoration {

    private static final int[] ATTRS = new int[]{android.R.attr.listDivider};

    private Drawable divider;

    /**
     * Default divider will be used
     */
    public DividerItemDecoration(Context context) {
        final TypedArray styledAttributes = context.obtainStyledAttributes(ATTRS);
        divider = styledAttributes.getDrawable(0);
        styledAttributes.recycle();
    }

    /**
     * Custom divider will be used
     */
    public DividerItemDecoration(Context context, int resId) {
        divider = ContextCompat.getDrawable(context, resId);
    }

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

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

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

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

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

Você pode chamar o primeiro construtor que usa os atributos padrão Android divider, ou o segundo que usa o seu próprio desenhável, por exemplo drawable/divider.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <size android:height="1dp" />
    <solid android:color="#ff992900" />
</shape>

Nota: Se quiser que o separador seja desenhado sobre {[74] } os seus itens, sobreponha onDrawOver() método em vez disso.

Utilização

Para usar a sua nova classe adicione VerticalSpaceItemDecoration ou DividerSpaceItemDecoration a RecyclerView, por exemplo no método do seu fragmento onCreateView():

private static final int VERTICAL_ITEM_SPACE = 48;
private RecyclerView recyclerView;
private LinearLayoutManager linearLayoutManager;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_feed, container, false);

    recyclerView = (RecyclerView) rootView.findViewById(R.id.fragment_home_recycler_view);
    linearLayoutManager = new LinearLayoutManager(getActivity());
    recyclerView.setLayoutManager(linearLayoutManager);

    //add ItemDecoration
    recyclerView.addItemDecoration(new VerticalSpaceItemDecoration(VERTICAL_ITEM_SPACE));
    //or
    recyclerView.addItemDecoration(new DividerItemDecoration(getActivity()));
    //or
    recyclerView.addItemDecoration(
            new DividerItemDecoration(getActivity(), R.drawable.divider));

    recyclerView.setAdapter(...);

    return rootView;
}

Há também a biblioteca de Lucas Rocha, que supostamente simplifica o processo de Decoração dos itens. Mas não tentei.

Entre as suas características estão:

  • uma colecção de decorações de material, incluindo:
  • espaço entre os itens separadores Horizontal/vertical.
  • lista ponto
 956
Author: EyesClear, 2016-10-25 11:04:51

Basta adicionar

recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),
                DividerItemDecoration.VERTICAL));

Também pode ser necessário adicionar a dependência
compile 'com.android.support:recyclerview-v7:27.1.0'

Editar:

Para personalizá-lo um pouco você pode adicionar um desenhável personalizado:

DividerItemDecoration itemDecorator = new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL);
itemDecorator.setDrawable(ContextCompat.getDrawable(getContext(), R.drawable.divider));

Pode usar qualquer desenho personalizado, por exemplo:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <solid android:color="@color/colorPrimary"/>
    <size android:height="0.5dp"/>
</shape>
 269
Author: Leo Droidcoder, 2018-06-20 12:04:29
Posso direccionar a sua atenção para este ficheiro em particular sobre o Github, de Alex Fu?: https://gist.github.com/alexfu/0f464fc3742f134ccd1e É a decoração da Divisão.java example file "pulled straight from the support demos". ( https://plus.google.com/103498612790395592106/posts/VVEB3m7NkSS) Fui capaz de obter linhas divisórias bem depois de importar este ficheiro no meu projecto e adicioná-lo como uma decoração de itens à vista do reciclador. Eis como a minha uma vista onCreateView parece-se com o meu fragmento que contém o Recyclerview:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_recycler_view, container, false);

    mRecyclerView = (RecyclerView) rootView.findViewById(R.id.my_recycler_view);
    mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));

    mRecyclerView.setHasFixedSize(true);
    mLayoutManager = new LinearLayoutManager(getActivity());
    mRecyclerView.setLayoutManager(mLayoutManager);
    mRecyclerView.setItemAnimator(new DefaultItemAnimator());

    return rootView;
}
Tenho a certeza que é possível fazer mais estilo, mas é um ponto de partida. :)
 239
Author: Duy Nguyen, 2014-07-21 18:29:25

Implementação simples ItemDecoration para espaços iguais entre todos os itens.

public class SpacesItemDecoration extends RecyclerView.ItemDecoration {
    private int space;

    public SpacesItemDecoration(int space) {
        this.space = space;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        outRect.left = space;
        outRect.right = space;
        outRect.bottom = space;

        // Add top margin only for the first item to avoid double space between items
        if(parent.getChildAdapterPosition(view) == 0) {
            outRect.top = space;
        }
    }
}
 131
Author: SergeyA, 2017-07-25 03:32:39

O simples é definir a cor de fundo para RecyclerView e uma cor de fundo diferente para os itens. Aqui está um exemplo ...

<android.support.v7.widget.RecyclerView
    android:background="#ECEFF1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scrollbars="vertical"/>

E o item TextView (pode ser qualquer coisa) com a margem inferior " x " dp ou px.

<TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginBottom="1dp"
    android:background="#FFFFFF"/>

A saída ...

enter image description here

 93
Author: Madan Sapkota, 2016-07-08 16:29:18
Acho que usar um divisor simples vai ajudar-te.

Adicionar divisor a cada item:
1-adicione isto à pasta desenhável .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="#999999" />
</shape>

2-Criar uma classe Simplesdevideridadedecoração
usei este exemplo para definir esta classe:
https://gist.github.com/polbins/e37206fbc444207c0e92

package com.example.myapp;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import com.example.myapp.R;

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

public SimpleDividerItemDecoration(Resources resources) {
    mDivider = resources.getDrawable(R.drawable.line_divider);
}

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

    int childCount = parent.getChildCount();
    for (int i = 0; i < childCount; i++) {
        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);
    }
  }
}


3- na actividade ou fragmento que utiliza RecyclerView, no interior do onCreateView adicione isto:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
 RecyclerView myRecyclerView = (RecyclerView) layout.findViewById(R.id.my_recycler_view);
 myRecyclerView.addItemDecoration(new SimpleDividerItemDecoration(getResources()));
 ....
 }


4- a adicionar espaçamento entre itens
só precisa de adicionar uma propriedade de enchimento à sua área de itens

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:padding="4dp"
>
..... item structure
</RelativeLayout>
 37
Author: Belal mazlom, 2015-04-04 13:12:53

Como eu defini ItemAnimators. O ItemDecorator não entra nem sai juntamente com a animação.

Acabei simplesmente por ter uma linha de visualização no meu ficheiro de disposição de cada item. Resolveu o meu caso. Parecia ser muita feitiçaria para um simples divisor. Ou posso estar a perder o seu verdadeiro uso.

<View
    android:layout_width="match_parent"
    android:layout_height="1px"
    android:layout_marginLeft="5dp"
    android:layout_marginRight="5dp"
    android:background="@color/lt_gray"/>
 25
Author: Javanator, 2016-09-12 13:12:49

Uma vez que não há uma maneira certa de implementar isto ainda adequadamente usando o design do Material, eu apenas fiz o seguinte truque para adicionar um divisor diretamente no item da lista:

<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/dividerColor"/>
 21
Author: Yoann Hercouet, 2016-04-13 18:22:09

ACTUALIZAÇÃO DE OUTUBRO DE 2016

Com a biblioteca de suporte v25. 0. 0 existe finalmente uma implementação predefinida dos separadores horizontais e verticais básicos disponíveis!

Https://developer.android.com/reference/android/support/v7/widget/DividerItemDecoration.html

 12
Author: friday, 2016-10-20 08:12:49

Isto não resolve realmente o problema, mas como uma solução temporária, você pode definir a propriedade useCompatPadding no cartão na sua disposição XML para fazer com que seja medida da mesma forma que acontece nas versões pré-Lollipop.

card_view:cardUseCompatPadding="true"
 9
Author: Kevin Grant, 2014-12-13 20:13:56
Adiciona uma margem à tua opinião, funcionou comigo.
android:layout_marginTop="10dp"

Se você apenas deseja adicionar igual espaçamento e quero fazê-lo em XML, apenas o conjunto padding para o seu RecyclerView e igual quantidade de layoutMargin para o item que você inflar em seu RecyclerView, e deixar a cor de fundo determinar o espaçamento de cor.

 9
Author: Quantum Mattter, 2017-02-05 12:16:55

Se alguém está à procura de adicionar apenas, digamos, espaço 10dp entre os itens, você pode fazê-lo definindo um desenhável para DividerItemDecoration:

DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(
    recyclerView.getContext(),
    layoutManager.getOrientation()
);

dividerItemDecoration.setDrawable(
    ContextCompat.getDrawable(getContext(), R.drawable.divider_10dp)
); 

Em que divider_10dp é um recurso mobilizável que contém:

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <size android:height="10dp"/>
    <solid android:color="@android:color/transparent"/>
</shape>
 9
Author: Praveen Singh, 2017-07-17 06:09:17

Para aqueles que estão à procura apenas de espaços entre os itens no RecyclerView, Veja a minha abordagem onde obtém espaços iguais entre todos os itens, excepto nos primeiros e últimos onde dei um acolchoamento maior. Só aplico estofos à esquerda / direita na horizontal LayoutManager e à cima/baixo na vertical LayoutManager.

public class PaddingItemDecoration extends RecyclerView.ItemDecoration {

    private int mPaddingPx;
    private int mPaddingEdgesPx;

    public PaddingItemDecoration(Activity activity) {
        final Resources resources = activity.getResources();
        mPaddingPx = (int) resources.getDimension(R.dimen.paddingItemDecorationDefault);
        mPaddingEdgesPx = (int) resources.getDimension(R.dimen.paddingItemDecorationEdge);
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);

        final int itemPosition = parent.getChildAdapterPosition(view);
        if (itemPosition == RecyclerView.NO_POSITION) {
            return;
        }
        int orientation = getOrientation(parent);
        final int itemCount = state.getItemCount();

        int left = 0;
        int top = 0;
        int right = 0;
        int bottom = 0;

        /** HORIZONTAL */
        if (orientation == LinearLayoutManager.HORIZONTAL) {
            /** all positions */
            left = mPaddingPx;
            right = mPaddingPx;

            /** first position */
            if (itemPosition == 0) {
                left += mPaddingEdgesPx;
            }
            /** last position */
            else if (itemCount > 0 && itemPosition == itemCount - 1) {
                right += mPaddingEdgesPx;
            }
        }
        /** VERTICAL */
        else {
            /** all positions */
            top = mPaddingPx;
            bottom = mPaddingPx;

            /** first position */
            if (itemPosition == 0) {
                top += mPaddingEdgesPx;
            }
            /** last position */
            else if (itemCount > 0 && itemPosition == itemCount - 1) {
                bottom += mPaddingEdgesPx;
            }
        }

        if (!isReverseLayout(parent)) {
            outRect.set(left, top, right, bottom);
        } else {
            outRect.set(right, bottom, left, top);
        }
    }

    private boolean isReverseLayout(RecyclerView parent) {
        if (parent.getLayoutManager() instanceof LinearLayoutManager) {
            LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
            return layoutManager.getReverseLayout();
        } else {
            throw new IllegalStateException("PaddingItemDecoration can only be used with a LinearLayoutManager.");
        }
    }

    private int getOrientation(RecyclerView parent) {
        if (parent.getLayoutManager() instanceof LinearLayoutManager) {
            LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
            return layoutManager.getOrientation();
        } else {
            throw new IllegalStateException("PaddingItemDecoration can only be used with a LinearLayoutManager.");
        }
    }
}

Dimens.xml

<resources>
    <dimen name="paddingItemDecorationDefault">10dp</dimen>
    <dimen name="paddingItemDecorationEdge">20dp</dimen>
</resources>
 8
Author: Ryan Amaral, 2016-09-12 14:48:24
Isto é simples, não precisas de um código tão complicado.
    DividerItemDecoration divider = new 
    DividerItemDecoration(mRVMovieReview.getContext(), 
    DividerItemDecoration.VERTICAL);
    divider.setDrawable(ContextCompat.getDrawable(getBaseContext(), 
       R.drawable.line_divider));
    mRVMovieReview.addItemDecoration(divider);

Adicione isto no seu desenhador: 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:height="1dp" />
        <solid android:color="@android:color/black" />
    </shape>
 8
Author: Faheem, 2017-08-28 07:48:56
    Aqui está um simples hack para adicionar um divisor.
  • Basta adicionar um fundo para a disposição do seu item reciclador como se segue

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/shape_border"
        android:gravity="center"
        android:orientation="horizontal"
        android:padding="5dp">
    
    <ImageView
        android:id="@+id/imageViewContactLogo"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_marginRight="10dp"
        android:src="@drawable/ic_user" />
    
    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="0.92"
        android:gravity="center|start"
        android:orientation="vertical">
    
    <TextView
        android:id="@+id/textViewContactName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />
    
    <TextView
        android:id="@+id/textViewStatusOrNumber"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:singleLine="true"
        android:text=""
        android:textAppearance="?android:attr/textAppearanceMedium" />
    </LinearLayout>
    
    <TextView
        android:id="@+id/textViewUnreadCount"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="10dp"
        android:padding="5dp"
        android:text=""
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="@color/red"
        android:textSize="22sp" />
    
    <Button
        android:id="@+id/buttonInvite"
        android:layout_width="54dp"
        android:layout_height="wrap_content"
        android:background="@drawable/ic_add_friend" />
    </LinearLayout>
    
Criar a seguir à shape_bronteira.xml na pasta desenhável
  <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
      android:shape="rectangle" >
       <gradient
        android:angle="270"
        android:centerColor="@android:color/transparent"
        android:centerX="0.01"
        android:startColor="#000" />
    </shape>
Aqui está o resultado final, um RecyclerView com divisor.

Here is final result - a RecyclerView with divider.

 8
Author: O'one, 2017-11-06 15:20:25

Tirei a divisória de um gist mais antigo e simplifiquei-a para caber no meu caso de uso, e também a modifiquei para desenhar os divisores da forma como são desenhados em ListView, incluindo um divisor após o último item da lista. Isto também irá lidar com animações Itemanimadoras verticais:

1) Adicione esta classe ao seu projecto:

public class DividerItemDecoration extends RecyclerView.ItemDecoration {
    private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
    private Drawable divider;

    public DividerItemDecoration(Context context) {
        try {
            final TypedArray a = context.obtainStyledAttributes(ATTRS);
            divider = a.getDrawable(0);
            a.recycle();
        } catch (Resources.NotFoundException e) {
            // TODO Log or handle as necessary.
        }
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        if (divider == null) return;
        if (parent.getChildAdapterPosition(view) < 1) return;

        if (getOrientation(parent) == LinearLayoutManager.VERTICAL)
            outRect.top = divider.getIntrinsicHeight();
        else
            throw new IllegalArgumentException("Only usable with vertical lists");
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        if (divider == null) {
            super.onDrawOver(c, parent, state);
            return;
        }

        final int left = parent.getPaddingLeft();
        final int right = parent.getWidth() - parent.getPaddingRight();
        final int childCount = parent.getChildCount();

        for (int i = 0; i < childCount; ++i) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            final int size = divider.getIntrinsicHeight();
            final int top = (int) (child.getTop() - params.topMargin - size + child.getTranslationY());
            final int bottom = top + size;
            divider.setBounds(left, top, right, bottom);
            divider.draw(c);

            if (i == childCount - 1) {
                final int newTop = (int) (child.getBottom() + params.bottomMargin + child.getTranslationY());
                final int newBottom = newTop + size;
                divider.setBounds(left, newTop, right, newBottom);
                divider.draw(c);
            }
        }
    }

    private int getOrientation(RecyclerView parent) {
        if (!(parent.getLayoutManager() instanceof LinearLayoutManager))
            throw new IllegalStateException("Layout manager must be an instance of LinearLayoutManager");
        return ((LinearLayoutManager) parent.getLayoutManager()).getOrientation();
    }
}

2) Adicione o decorador à sua revisão:

recyclerView.addItemDecoration(new DividerItemDecoration(getActivity()));
 7
Author: Learn OpenGL ES, 2015-08-04 22:44:14

Retirado de uma pesquisa no google, adicione isto à sua descrição RecyclerView:

public class DividerItemDecoration extends RecyclerView.ItemDecoration {

private Drawable mDivider;
private boolean mShowFirstDivider = false;
private boolean mShowLastDivider = false;


public DividerItemDecoration(Context context, AttributeSet attrs) {
    final TypedArray a = context
            .obtainStyledAttributes(attrs, new int[]{android.R.attr.listDivider});
    mDivider = a.getDrawable(0);
    a.recycle();
}

public DividerItemDecoration(Context context, AttributeSet attrs, boolean showFirstDivider,
        boolean showLastDivider) {
    this(context, attrs);
    mShowFirstDivider = showFirstDivider;
    mShowLastDivider = showLastDivider;
}

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

public DividerItemDecoration(Drawable divider, boolean showFirstDivider,
        boolean showLastDivider) {
    this(divider);
    mShowFirstDivider = showFirstDivider;
    mShowLastDivider = showLastDivider;
}

@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
        RecyclerView.State state) {
    super.getItemOffsets(outRect, view, parent, state);
    if (mDivider == null) {
        return;
    }
    if (parent.getChildPosition(view) < 1) {
        return;
    }

    if (getOrientation(parent) == LinearLayoutManager.VERTICAL) {
        outRect.top = mDivider.getIntrinsicHeight();
    } else {
        outRect.left = mDivider.getIntrinsicWidth();
    }
}

@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
    if (mDivider == null) {
        super.onDrawOver(c, parent, state);
        return;
    }

    // Initialization needed to avoid compiler warning
    int left = 0, right = 0, top = 0, bottom = 0, size;
    int orientation = getOrientation(parent);
    int childCount = parent.getChildCount();

    if (orientation == LinearLayoutManager.VERTICAL) {
        size = mDivider.getIntrinsicHeight();
        left = parent.getPaddingLeft();
        right = parent.getWidth() - parent.getPaddingRight();
    } else { //horizontal
        size = mDivider.getIntrinsicWidth();
        top = parent.getPaddingTop();
        bottom = parent.getHeight() - parent.getPaddingBottom();
    }

    for (int i = mShowFirstDivider ? 0 : 1; i < childCount; i++) {
        View child = parent.getChildAt(i);
        RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

        if (orientation == LinearLayoutManager.VERTICAL) {
            top = child.getTop() - params.topMargin;
            bottom = top + size;
        } else { //horizontal
            left = child.getLeft() - params.leftMargin;
            right = left + size;
        }
        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(c);
    }

    // show last divider
    if (mShowLastDivider && childCount > 0) {
        View child = parent.getChildAt(childCount - 1);
        RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
        if (orientation == LinearLayoutManager.VERTICAL) {
            top = child.getBottom() + params.bottomMargin;
            bottom = top + size;
        } else { // horizontal
            left = child.getRight() + params.rightMargin;
            right = left + size;
        }
        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(c);
    }
}

private int getOrientation(RecyclerView parent) {
    if (parent.getLayoutManager() instanceof LinearLayoutManager) {
        LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
        return layoutManager.getOrientation();
    } else {
        throw new IllegalStateException(
                "DividerItemDecoration can only be used with a LinearLayoutManager.");
    }
}
}
 5
Author: kentarosu, 2015-05-13 17:19:21

Se quiser adicionar o mesmo espaço para os itens, a forma mais simples é adicionar enchimento superior+esquerdo para a RecycleView e margens direita+inferior aos itens do cartão.

Dimens.xml

<resources>
    <dimen name="divider">1dp</dimen>
</resources>

List_item.xml

<CardView
 android:layout_marginBottom="@dimen/divider"
 android:layout_marginRight="@dimen/divider">
 ...
</CardView>

Lista.xml

<RecyclerView
 android:paddingLeft="@dimen/divider"
 android:paddingTop="@dimen/divider"
/>
 4
Author: limitium, 2015-05-28 18:14:03

Podemos decorar os itens usando vários decoradores ligados ao recyclerview, tais como a separação:

Basta utilizar o seguinte ...extraído da resposta por EyesClear

public class DividerItemDecoration extends RecyclerView.ItemDecoration {

private static final int[] ATTRS = new int[]{android.R.attr.listDivider};

private Drawable mDivider;

/**
 * Default divider will be used
 */
public DividerItemDecoration(Context context) {
    final TypedArray styledAttributes = context.obtainStyledAttributes(ATTRS);
    mDivider = styledAttributes.getDrawable(0);
    styledAttributes.recycle();
}

/**
 * Custom divider will be used
 */
public DividerItemDecoration(Context context, int resId) {
    mDivider = ContextCompat.getDrawable(context, resId);
}

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

    int childCount = parent.getChildCount();
    for (int i = 0; i < childCount; i++) {
        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);
    }
}

} e então use o acima como segue

RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST);
recyclerView.addItemDecoration(itemDecoration);

Isto irá mostrar divisores entre cada item da lista como se mostra abaixo:

enter image description here

E para aqueles que estão à procura de mais detalhes pode verificar este guia usando o RecyclerView _ Codepath Cliffnotes Android

Algumas respostas sugerem o uso de margens, mas a captura é que : Se você adicionar ambas as margens de cima e de baixo, elas aparecerão ambas adicionadas entre os itens e eles serão muito grandes. Se você só adicionar qualquer um, não haverá nenhuma margem no topo ou no fundo de toda a lista. Se você adicionar metade da distância no topo, metade no fundo, as margens exteriores serão muito pequenas.

Assim, a única solução esteticamente correcta é o divisor que o sistema sabe onde aplicar corretamente: entre itens, mas não acima ou abaixo.

Por favor, avise-me de quaisquer dúvidas nos comentários abaixo:]

 4
Author: Anudeep Samaiya, 2017-05-23 12:10:45
Este elo funcionou como um encanto para mim.

Https://gist.github.com/lapastillaroja/858caf1a82791b6c1a36

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;

public class DividerItemDecoration extends RecyclerView.ItemDecoration {

    private Drawable mDivider;
    private boolean mShowFirstDivider = false;
    private boolean mShowLastDivider = false;


    public DividerItemDecoration(Context context, AttributeSet attrs) {
        final TypedArray a = context
                .obtainStyledAttributes(attrs, new int[]{android.R.attr.listDivider});
        mDivider = a.getDrawable(0);
        a.recycle();
    }

    public DividerItemDecoration(Context context, AttributeSet attrs, boolean showFirstDivider,
            boolean showLastDivider) {
        this(context, attrs);
        mShowFirstDivider = showFirstDivider;
        mShowLastDivider = showLastDivider;
    }

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

    public DividerItemDecoration(Drawable divider, boolean showFirstDivider,
            boolean showLastDivider) {
        this(divider);
        mShowFirstDivider = showFirstDivider;
        mShowLastDivider = showLastDivider;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
            RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        if (mDivider == null) {
            return;
        }
        if (parent.getChildPosition(view) < 1) {
            return;
        }

        if (getOrientation(parent) == LinearLayoutManager.VERTICAL) {
            outRect.top = mDivider.getIntrinsicHeight();
        } else {
            outRect.left = mDivider.getIntrinsicWidth();
        }
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        if (mDivider == null) {
            super.onDrawOver(c, parent, state);
            return;
        }

        // Initialization needed to avoid compiler warning
        int left = 0, right = 0, top = 0, bottom = 0, size;
        int orientation = getOrientation(parent);
        int childCount = parent.getChildCount();

        if (orientation == LinearLayoutManager.VERTICAL) {
            size = mDivider.getIntrinsicHeight();
            left = parent.getPaddingLeft();
            right = parent.getWidth() - parent.getPaddingRight();
        } else { //horizontal
            size = mDivider.getIntrinsicWidth();
            top = parent.getPaddingTop();
            bottom = parent.getHeight() - parent.getPaddingBottom();
        }

        for (int i = mShowFirstDivider ? 0 : 1; i < childCount; i++) {
            View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

            if (orientation == LinearLayoutManager.VERTICAL) {
                top = child.getTop() - params.topMargin;
                bottom = top + size;
            } else { //horizontal
                left = child.getLeft() - params.leftMargin;
                right = left + size;
            }
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }

        // show last divider
        if (mShowLastDivider && childCount > 0) {
            View child = parent.getChildAt(childCount - 1);
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            if (orientation == LinearLayoutManager.VERTICAL) {
                top = child.getBottom() + params.bottomMargin;
                bottom = top + size;
            } else { // horizontal
                left = child.getRight() + params.rightMargin;
                right = left + size;
            }
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    private int getOrientation(RecyclerView parent) {
        if (parent.getLayoutManager() instanceof LinearLayoutManager) {
            LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
            return layoutManager.getOrientation();
        } else {
            throw new IllegalStateException(
                    "DividerItemDecoration can only be used with a LinearLayoutManager.");
        }
    }
}

Depois na sua actividade:

mCategoryRecyclerView.addItemDecoration(
    new DividerItemDecoration(this, null));

Ou isto se estiver a usar um fragmento:

mCategoryRecyclerView.addItemDecoration(
    new DividerItemDecoration(getActivity(), null));
 3
Author: Micro, 2015-08-21 16:33:55

Adicionei uma linha no item da lista como abaixo

<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/dividerColor"/>

1px vai desenhar a linha fina.

Se quiser esconder o separador para a última linha, então divider.setVisiblity(View.GONE); na lista onBindViewHolder para o Item da última lista.

 3
Author: Raja Peela, 2016-07-01 11:49:01

Demasiado tarde, mas para GridLayoutManager uso isto:

public class GridSpacesItemDecoration : RecyclerView.ItemDecoration
{
    private int space;

    public GridSpacesItemDecoration(int space) {
        this.space = space;
    }

    public override void GetItemOffsets(Android.Graphics.Rect outRect, View view, RecyclerView parent, RecyclerView.State state)
    {
        var position = parent.GetChildLayoutPosition(view);

        /// Only for GridLayoutManager Layouts
        var manager = parent.GetLayoutManager() as GridLayoutManager;

        if (parent.GetChildLayoutPosition(view) < manager.SpanCount)
            outRect.Top = space;

        if (position % 2 != 0) {
            outRect.Right = space;
        }

        outRect.Left = space;
        outRect.Bottom = space;
    }
}
Este trabalho é para qualquer Contagem de espaço que tenha. Ollie.
 3
Author: Ollie Strevel, 2017-01-10 23:30:27

Você pode adicionar com programaticamente facilmente.

Se o teu Gestor de Layout for o Linearlayout, podes usar:

A separação é uma área de Reciclagem.Declaração que pode ser usado como divisor entre itens de um "LinearLayoutManager". Suporta orientações horizontais e verticais.

 mDividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
         mLayoutManager.getOrientation());
 recyclerView.addItemDecoration(mDividerItemDecoration);

Origem

 3
Author: Beyaz, 2017-01-22 06:48:21

public class CommonItemSpaceDecoration extends RecyclerView.ItemDecoration {
    private int mSpace = 0;
    private boolean mVerticalOrientation = true;

    public CommonItemSpaceDecoration(int space) {
        this.mSpace = space;
    }

    public CommonItemSpaceDecoration(int space, boolean verticalOrientation) {
        this.mSpace = space;
        this.mVerticalOrientation = verticalOrientation;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        outRect.top = SizeUtils.dp2px(view.getContext(), mSpace);
        if (mVerticalOrientation) {
            if (parent.getChildAdapterPosition(view) == 0) {
                outRect.set(0, SizeUtils.dp2px(view.getContext(), mSpace), 0, SizeUtils.dp2px(view.getContext(), mSpace));
            } else {
                outRect.set(0, 0, 0, SizeUtils.dp2px(view.getContext(), mSpace));
            }
        } else {
            if (parent.getChildAdapterPosition(view) == 0) {
                outRect.set(SizeUtils.dp2px(view.getContext(), mSpace), 0, 0, 0);
            } else {
                outRect.set(SizeUtils.dp2px(view.getContext(), mSpace), 0, SizeUtils.dp2px(view.getContext(), mSpace), 0);
            }
        }


    }
}

Isto irá adicionar espaço no topo e no fundo de cada item(ou esquerda e direita).Depois pode colocá-lo na sua recyclerView.

recyclerView.addItemDecoration(new CommonItemSpaceDecoration(16));

Sizeutiles.java

public class SizeUtils {
    public static int dp2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}
 3
Author: wizChen, 2017-02-28 09:16:06

Uma solução muito fácil é usar RecyclerView-FlexibleDivider

Adicionar dependência:

compile 'com.yqritc:recyclerview-flexibledivider:1.4.0'

Adicione ao seu recyclerview:

recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(context).build());
E acabou-se!
 2
Author: Cristan, 2016-09-22 12:38:44

1.Uma das maneiras é usando cardview e recycler view juntos {[4] } podemos facilmente adicionar efeito como divisor. ex.https://developer.android.com/training/material/lists-cards.html

2.e outra é adicionando ver como divisor a list_ item_layout da recycler view .

        <View
            android:id="@+id/view1"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="@color/colorAccent" />
 2
Author: vicky, 2017-01-31 08:43:21

Implemente a sua própria versão de RecyclerView.Itemdecoração

public class SpacingItemDecoration extends RecyclerView.ItemDecoration {
    private int spacingPx;
    private boolean addStartSpacing;
    private boolean addEndSpacing;

    public SpacingItemDecoration(int spacingPx) {
        this(spacingPx, false, false);
    }

    public SpacingItemDecoration(int spacingPx, boolean addStartSpacing, boolean addEndSpacing) {
        this.spacingPx = spacingPx;
        this.addStartSpacing = addStartSpacing;
        this.addEndSpacing = addEndSpacing;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        if (spacingPx <= 0) {
            return;
        }

        if (addStartSpacing && parent.getChildLayoutPosition(view) < 1 || parent.getChildLayoutPosition(view) >= 1) {
            if (getOrientation(parent) == LinearLayoutManager.VERTICAL) {
                outRect.top = spacingPx;
            } else {
                outRect.left = spacingPx;
            }
        }

        if (addEndSpacing && parent.getChildAdapterPosition(view) == getTotalItemCount(parent) - 1) {
            if (getOrientation(parent) == LinearLayoutManager.VERTICAL) {
                outRect.bottom = spacingPx;
            } else {
                outRect.right = spacingPx;
            }
        }
    }

    private int getTotalItemCount(RecyclerView parent) {
        return parent.getAdapter().getItemCount();
    }

    private int getOrientation(RecyclerView parent) {
        if (parent.getLayoutManager() instanceof LinearLayoutManager) {
            return ((LinearLayoutManager) parent.getLayoutManager()).getOrientation();
        } else {
            throw new IllegalStateException("SpacingItemDecoration can only be used with a LinearLayoutManager.");
        }
    }
}
 1
Author: e.shishkin, 2015-06-24 17:09:47

O RecyclerView é um pouco diferente do ListView. Na verdade, o RecyclerView precisa de uma estrutura semelhante. Por exemplo, a LinearLayout. O LinearLayout tem parâmetros para a divisão de cada elemento. No código abaixo eu tenho um RecyclerView composto por objetos CardView dentro de um LinearLayout com um "enchimento" que colocará algum espaço entre os itens. Faz com que esse espaço seja muito pequeno e tens uma linha.

Aqui está a vista do Reciclador em recyclerview_layout.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".ToDoList">

    <!-- A RecyclerView with some commonly used attributes -->
    <android.support.v7.widget.RecyclerView
        android:id="@+id/todo_recycler_view"
        android:scrollbars="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>
E aqui está como cada item se parece (e mostra como dividido devido ao android:enchimento no LinearLayout que envolve tudo.) em outro arquivo: cards_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    **android:padding="@dimen/activity_vertical_margin"**>
    <!-- A CardView that contains a TextView -->
    <android.support.v7.widget.CardView
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/card_view"
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:elevation="30dp"
        card_view:cardElevation="3dp">
            <TextView
                android:id="@+id/info_text"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                />
    </android.support.v7.widget.CardView>
</LinearLayout>
 1
Author: fiacobelli, 2015-07-25 05:33:27
Tenho uma forma muito simples de adicionar um separador em RecyclerView. Use um adaptador personalizado para modificar a disposição da vista recicler e, em seguida, juntamente com os itens da vista recicler adicionar LinearLayout com uma cor de fundo (que será a cor do separador) e adicionar uma altura de 1dp (ou de acordo com o seu requisito) e largura para corresponder ao Pai. Aqui está um código de amostra.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="18dp">

    <TextView
        android:id="@+id/list_row_SNO"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight=".8"
        android:layout_gravity="end"
        android:text="44."
        android:textAlignment="center"
        android:textSize="24sp"
        android:textColor="@color/colorBlack"
        android:fontFamily="sans-serif-condensed" />

    <TextView
        android:id="@+id/list_row_Heading"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight=".2"
        android:layout_gravity="start"
        android:text="Student's application for leave and this what"
        android:textAlignment="textStart"
        android:textSize="24sp"
        android:textColor="@color/colorBlack"
        android:fontFamily="sans-serif-condensed" />

</LinearLayout>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:background="@color/colorHighlight">
</LinearLayout>

 1
Author: Nabajyoti Das, 2017-02-04 09:07:25
public class VerticalItemDecoration extends RecyclerView.ItemDecoration {

private boolean verticalOrientation = true;
private int space = 10;

public VerticalItemDecoration(int value, boolean verticalOrientation) {
    this.space = value;
    this.verticalOrientation = verticalOrientation;
}

@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
                           RecyclerView.State state) {
    //skip first item in the list
    if (parent.getChildAdapterPosition(view) != 0) {
        if (verticalOrientation) {
            outRect.set(space, 0, 0, 0);
        } else if (!verticalOrientation) {
            outRect.set(0, space, 0, 0);
        }
    }
}
}

mCompletedShippingRecyclerView.addItemDecoration(new VerticalItemDecoration(20,false)); 
 1
Author: Amardeep, 2017-02-09 11:52:49