viewholder studio seleccionar recyclerview propiedades item eventos eliminar elemento ejemplo android android-recyclerview divider

android - studio - ¿Cómo agregar divisores y espacios entre elementos en RecyclerView?



recyclerview seleccionar item (30)

ACTUALIZACIÓN DE OCTUBRE 2016

¡Con la biblioteca de soporte v25.0.0 finalmente hay una implementación predeterminada de divisores básicos horizontales y verticales disponibles!

DividerItemDecoration

Este es un ejemplo de cómo se podría haber hecho anteriormente en la clase ListView , usando los parámetros divider y dividerHeight :

<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"/>

Sin embargo, no veo tal posibilidad en la clase RecyclerView .

<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"/>

En ese caso, ¿está bien definir márgenes y / o agregar una vista divisoria personalizada directamente en el diseño de un elemento de la lista o hay una mejor manera de lograr mi objetivo?


Agregue un margen a su vista, funcionó para mí.

android:layout_marginTop="10dp"

Si solo desea agregar un espaciado igual y desea hacerlo en XML , simplemente configure el padding en RecyclerView y una cantidad igual de layoutMargin en el elemento que infla en RecyclerView , y deje que el color de fondo determine el color del espaciado.


Como he puesto en el tema de los ItemAnimators . El ItemDecorator no entra ni sale junto con la animación.

Simplemente terminé teniendo una línea de vista en mi archivo de diseño de vista de artículo de cada artículo. Se solucionó mi caso. DividerItemDecoration consideraba una gran parte de la brujería para un simple divisor. O podría estar perdiendo su uso real.

<View android:layout_width="match_parent" android:layout_height="1px" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:background="@color/lt_gray"/>


Creo que usar un divisor simple te ayudará

Para agregar divisor a cada elemento:
1- Agregar esto al directorio dibujable 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="#999999" /> </shape>

2- Crear la clase SimpleDividerItemDecoration
Utilicé este ejemplo para definir esta clase:
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- En la actividad o fragmento que utilizando RecyclerView, dentro de onCreateView agregue esto:

@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- Para agregar espacio entre los elementos.
solo necesita agregar propiedades de relleno a la vista de artículo

<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>


El sencillo es establecer el color de fondo para RecyclerView y el color de fondo diferente para los elementos. Aquí hay un ejemplo ...

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

y el elemento TextView (aunque puede ser cualquier cosa) con el margen inferior "x" dp o px.

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

La salida ...


Esto es simple, no necesitas código tan complicado

<?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>

Agrega esto en tu dibujo: line_divider.xml

<?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>


Esto realmente no resuelve el problema, pero como solución temporal temporal, puede configurar la propiedad useCompatPadding en la tarjeta en su diseño XML para que mida lo mismo que en las versiones anteriores a Lollipop.

card_view:cardUseCompatPadding="true"


Para aquellos que solo buscan espacios entre los elementos en RecyclerView vea mi enfoque en el que obtiene espacios iguales entre todos los elementos, excepto en los primeros y últimos elementos en los que proporcioné un relleno más grande. Solo aplico el relleno a la izquierda / derecha en el LayoutManager horizontal y en la parte superior / inferior en el LayoutManager vertical.

DividerItemDecoration divider = new DividerItemDecoration(mRVMovieReview.getContext(), DividerItemDecoration.VERTICAL); divider.setDrawable(ContextCompat.getDrawable(getBaseContext(), R.drawable.line_divider)); mRVMovieReview.addItemDecoration(divider);

dimens.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>


Podría dirigir su atención a este archivo en particular en Github por Alex Fu: https://gist.github.com/alexfu/0f464fc3742f134ccd1e

Es el archivo de ejemplo DividerItemDecoration.java "extraído directamente de las demostraciones de soporte". ( https://plus.google.com/103498612790395592106/posts/VVEB3m7NkSS )

Pude obtener líneas divisoras muy bien después de importar este archivo en mi proyecto y agregarlo como elemento decorativo a la vista del reciclador.

Así es como se ve mi onCreateView en mi fragmento que contiene el 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; }

Estoy seguro de que se puede hacer un estilo adicional, pero es un punto de partida. :)


Si alguien está buscando agregar solo, por ejemplo, un espacio de 10dp entre los elementos, puede hacerlo configurando un DividerItemDecoration para DividerItemDecoration :

DividerItemDecoration dividerItemDecoration = new DividerItemDecoration( recyclerView.getContext(), layoutManager.getOrientation() ); dividerItemDecoration.setDrawable( ContextCompat.getDrawable(getContext(), R.drawable.divider_10dp) );

Donde divider_10dp es un recurso divider_10dp que contiene:

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <size android:height="10dp"/> <solid android:color="@android:color/transparent"/> </shape>


Solo agrega

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

También es posible que necesite agregar la dependencia.
compile ''com.android.support:recyclerview-v7:27.1.0''

EDITAR:

Para personalizarlo un poco puedes agregar un dibujo personalizado:

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

Usted es libre de usar cualquier dibujo personalizable, por ejemplo:

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="@color/colorPrimary"/> <size android:height="0.5dp"/> </shape>


Tomado de una búsqueda en Google, agregue este ItemDecoration a su 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."); } } }


Ya que no hay una manera correcta de implementar esto, pero utilizando correctamente el Diseño de Materiales, simplemente hice el siguiente truco para agregar un divisor en el elemento de la lista directamente:

<View android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/dividerColor"/>


Yo bifurqué DividerItemDecoration de una idea anterior y lo simplifiqué para que se ajustara a mi caso de uso, y también lo modifiqué para dibujar los divisores de la forma en que están dibujados en ListView, incluido un divisor después del último elemento de la lista. Esto también manejará animaciones verticales de ItemAnimator

1) Agrega esta clase a tu proyecto:

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) Agregue el decorador a su RecylerView:

recyclerView.addItemDecoration(new DividerItemDecoration(getActivity()));


ItemDecoration simple de ItemDecoration para espacios iguales entre todos los artículos.

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; } } }


Actualización de Octubre 2016

La versión 25.0.0 de la biblioteca de soporte de Android introdujo la clase DividerItemDecoration :

DividerItemDecoration es un RecyclerView.ItemDecoration que se puede usar como divisor entre los elementos de un LinearLayoutManager. Soporta orientaciones tanto HORIZONTALES como VERTICALES.

Uso:

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

Respuesta anterior

Algunas respuestas utilizan métodos que han quedado obsoletos o no dan una solución completa, por lo que traté de hacer un resumen breve y actualizado.

A diferencia de ListView , la clase RecyclerView no tiene parámetros relacionados con el divisor. En su lugar, necesita extender ItemDecoration , una clase interna de RecyclerView :

Un ItemDecoration permite que la aplicación agregue un dibujo especial y un desplazamiento de diseño a vistas de artículos específicos del conjunto de datos del adaptador. Esto puede ser útil para dibujar divisores entre elementos, resaltados, límites de agrupación visual y más.

Todas las decoraciones de elementos se dibujan en el orden en que se agregaron, antes de las vistas de elementos (en onDraw ()) y después de los elementos (en onDrawOver (Canvas, RecyclerView, RecyclerView.State).

ItemDecoration vertical ItemDecoration

Extienda ItemDecoration , agregue un constructor personalizado que tome la altura del espacio como parámetro y anule el método getItemOffsets() :

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; } }

Si no desea insertar espacio debajo del último elemento, agregue la siguiente condición:

if (parent.getChildAdapterPosition(view) != parent.getAdapter().getItemCount() - 1) { outRect.bottom = verticalSpaceHeight; }

Nota: también puede modificar las outRect.top , outRect.left y outRect.right para el efecto deseado.

ItemDecoration

Extienda ItemDecoration y anule el método onDraw() :

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); } } }

Puede llamar al primer constructor que usa los atributos de división de Android predeterminados, o al segundo que usa su propio dibujable, por ejemplo 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: si desea que el divisor se onDrawOver() sobre sus elementos, onDrawOver() método onDrawOver() lugar.

Uso

Para usar su nueva clase, agregue VerticalSpaceItemDecoration o DividerSpaceItemDecoration a RecyclerView , por ejemplo, en el método onCreateView() su fragmento:

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; }

También está la biblioteca de Lucas Rocha, que se supone simplifica el proceso de decoración del artículo. Aunque no lo he intentado.

Entre sus features destacan:

  • Una colección de artículos decorativos que incluyen:
  • Separación de elementos Separadores horizontales / verticales.
  • Elemento de lista

Este enlace funcionó como un encanto para mí:

ItemDecoration

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."); } } }

Luego en tu actividad:

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

O esto si está utilizando un fragmento:

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


He añadido una línea en el elemento de lista como abajo

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

1px dibujará la línea delgada.

Si desea ocultar el divisor para la última fila, divider.setVisiblity(View.GONE);en onBindViewHolder para el último elemento de la lista.


Implementar su propia versión de RecyclerView.ItemDecoration

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."); } } }


Podemos decorar los elementos utilizando varios decoradores adjuntos a la vista de reciclaje, como DividerItemDecoration:

Simplemente usa lo siguiente ... tomado de la respuesta por

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); } }

} y luego usa lo anterior como sigue

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

Esto mostrará divisiones entre cada elemento dentro de la lista como se muestra a continuación:

Y para aquellos que estén buscando más detalles, pueden consultar esta guía Cómo utilizar RecyclerView _ CodePath Android Cliffnotes

Algunas respuestas aquí sugieren el uso de márgenes, pero el problema es que: si agrega los márgenes superior e inferior, aparecerán agregados entre los elementos y serán demasiado grandes. Si solo agrega cualquiera de los dos, no habrá margen en la parte superior o inferior de toda la lista. Si agrega la mitad de la distancia en la parte superior, la mitad en la parte inferior, los márgenes exteriores serán demasiado pequeños.

Por lo tanto, la única solución estéticamente correcta es el divisor que el sistema sabe dónde aplicar correctamente: entre los elementos pero no por encima o por debajo de los elementos.

Por favor, hágamelo saber de cualquier duda en los comentarios a continuación :)


Se puede agregar con facilidad programáticamente.

Si su Layout Manager es Linearlayout, entonces puede usar:

DividerItemDecoration es un RecyclerView.ItemDecoration que se puede usar como divisor entre los elementos de un LinearLayoutManager. Soporta orientaciones tanto HORIZONTALES como VERTICALES.

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

DividerItemDecoration


Si desea agregar el mismo espacio para los elementos, la forma más sencilla es agregar el relleno superior + izquierdo para RecycleView y los márgenes inferior derecho + derecho a los elementos de la tarjeta.

dimens.xml

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

list_item.xml

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

list.xml

<RecyclerView android:paddingLeft="@dimen/divider" android:paddingTop="@dimen/divider" />


1.One of the Way es mediante el uso de Cardview y Recycler View , podemos agregar fácilmente el efecto como divisor. ex. https://developer.android.com/training/material/lists-cards.html

2.y otra es agregando view como divisor a list_item_layout de recycler view .

<View android:id="@+id/view1" android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/colorAccent" />


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); } } } }

Esto agregará espacio en la parte superior e inferior de cada elemento (o izquierda y derecha). Luego, puede configurarlo en su recyclerView.

recyclerView.addItemDecoration(new CommonItemSpaceDecoration(16));

SizeUtils.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); } }


Demasiado tarde pero para GridLayoutManageresto uso:

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 trabajo para cualquier lapso cuenta.

Ollie.


El RecyclerViewes un poco diferente del ListView. En realidad, las RecyclerViewnecesidades de una ListViewestructura similar en ella. Por ejemplo, a LinearLayout. El LinearLayouttiene parámetros para la división de cada elemento. En el código a continuación, tengo una lista RecyclerViewde CardViewobjetos dentro de LinearLayoutun "relleno" que colocará un espacio entre los elementos. Haz ese espacio realmente pequeño y obtienes una línea.

Aquí está la vista del reciclador en 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>

Y aquí es cómo se ve cada elemento (y se muestra dividido debido a Android: relleno en el LinearLayout que rodea todo.) En otro archivo: 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>


Tengo una forma muy sencilla de agregar un divisor en RecyclerView. Use un adaptador personalizado para modificar el diseño de la vista del reciclador y luego, junto con los elementos de la vista del reciclador, agregue LinearLayout con un color de fondo (que será el color divisor) y agregue una altura de 1dp (o según sus requisitos) y el ancho para que coincida con el padre .

Aquí hay un código de ejemplo.

<?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>


Una solución realmente fácil es usar RecyclerView-FlexibleDivider

Añadir dependencia:

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

Agregue a su recyclerview:

recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(context).build());

¡Y tu estas listo!


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));


  • Aquí es simple truco para agregar divisor
  • Solo agregue un fondo al diseño de su elemento de reciclado de la siguiente manera

    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."); } } }

Crea el siguiente shape_border.xml en la carpeta dibujable

<resources> <dimen name="paddingItemDecorationDefault">10dp</dimen> <dimen name="paddingItemDecorationEdge">20dp</dimen> </resources>

Aquí está el resultado final - un RecyclerView con divisor.