¿Cómo evitar el espacio doble entre los elementos cuando se utiliza RecyclerView con StaggeredGridLayoutManager?

Estoy usando RecyclerView con StaggeredGridLayoutManager para hacer una lista de dos columnas. Pero cómo establecer un margen derecho entre la columna izquierda y la columna derecha. He utilizado este código para hacer el margen derecho desde arriba, pero cómo resolver el doble espacio entre las columnas.

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 or second item to avoid double space between items // Add top margin only for the first or second item to avoid double space between items if((parent.getChildCount() > 0 && parent.getChildPosition(view) == 0) || (parent.getChildCount() > 1 && parent.getChildPosition(view) == 1)) outRect.top = space; } 

Y en Actividad:

 recyclerView.addItemDecoration(new SpacesItemDecoration(20)); 

He intentado usar view.getX() , siempre devuelve 0.

¿Alguien puede ayudarme? ¡Muchas gracias!

En su caso, puede establecer el margen de ambos a la RecyclerView. Pero en mi caso hay una imagen coincide con el ancho de la pantalla en el RecyclerView, y yo uso la ItemDecoration para resolver el problema.

  class ViewItemDecoration extends RecyclerView.ItemDecoration { public ViewItemDecoration() { } @Override public void getItemOffsets(Rect outRect, final View view, final RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); int position = parent.getChildAdapterPosition(view); int spanIndex = ((StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams()).getSpanIndex(); int type = adapter.getItemViewType(position); switch(type){ case YOUR_ITEMS: if (spanIndex == 0) { outRect.left = 10; outRect.right = 5; } else {//if you just have 2 span . Or you can use (staggeredGridLayoutManager.getSpanCount()-1) as last span outRect.left = 5; outRect.right = 10; } } } } 

El código siguiente controlará StaggeredGridLayoutManager, GridLayoutManager y LinearLayoutManager.

 public class SpacesItemDecoration extends RecyclerView.ItemDecoration { private int halfSpace; public SpacesItemDecoration(int space) { this.halfSpace = space / 2; } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { if (parent.getPaddingLeft() != halfSpace) { parent.setPadding(halfSpace, halfSpace, halfSpace, halfSpace); parent.setClipToPadding(false); } outRect.top = halfSpace; outRect.bottom = halfSpace; outRect.left = halfSpace; outRect.right = halfSpace; } } 

Lo solucioné yo mismo ajustando el margen del elemento y el relleno de RecyclerView. Tanto el margen como el relleno son la mitad del espacio esperado, por lo que el problema desapareció.

Establecer el espacio izquierdo / derecho diferente en ItemDecoration de acuerdo a spanindex sólo funciona bien para la vista del artículo tiene un tamaño fijo. Si la vista de elemento contiene una vista de imagen, establezca wrap_content en altura, la vista de elemento puede cambiar la posición de span, pero el índice de span no se actualizará como desee, el margen será un desastre.

Mi manera es, usando el espacio simétrico izquierdo / derecho para el artículo de la visión.

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // init recyclerView = (RecyclerView) rv.findViewById(R.id.img_waterfall); layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); recyclerView.setLayoutManager(layoutManager); recyclerView.setAdapter(new MyAdapter(getContext())); recyclerView.addItemDecoration(new SpacesItemDecoration( getResources().getDimensionPixelSize(R.dimen.space))); } private static class SpacesItemDecoration extends RecyclerView.ItemDecoration { private final int space; public SpacesItemDecoration(int space) { this.space = space; } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { outRect.bottom = 2 * space; int pos = parent.getChildAdapterPosition(view); outRect.left = space; outRect.right = space; if (pos < 2) outRect.top = 2 * space; } } 

A continuación, establezca el mismo relleno para RecylerView (izquierda / derecha) android: paddingLeft = "@ dimen / space" android: paddingRight = "@ dimen / space"

  <android.support.v7.widget.RecyclerView android:id="@+id/img_waterfall" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/space" android:paddingRight="@dimen/space"/> 

Cambiaría y modificaría ligeramente la respuesta de la pregunta relativa

 public class SpacesItemDecoration extends RecyclerView.ItemDecoration { private final int mSpace; public SpacesItemDecoration(int space) { this.mSpace = space; } @Override public void getItemOffsets(Rect outRect, final View view, final RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); int position = parent.getChildAdapterPosition(view); int spanIndex = ((StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams()).getSpanIndex(); if (spanIndex == 0) { outRect.left = 30; outRect.right = 15; } else {//if you just have 2 span . Or you can use (staggeredGridLayoutManager.getSpanCount()-1) as last span outRect.left = 15; outRect.right = 30; } outRect.bottom = 30; // Add top margin only for the first item to avoid double space between items if (parent.getChildAdapterPosition(view) == 0) { outRect.top = 30; outRect.right = 30; } } } 
 public class EqualGapItemDecoration extends RecyclerView.ItemDecoration { private int spanCount; private int spacing; public EqualGapItemDecoration(int spanCount, int spacing) { this.spanCount = spanCount; this.spacing = spacing; } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams(); if (layoutParams.isFullSpan()) { outRect.set(0, 0, 0, 0); } else { int spanIndex = layoutParams.getSpanIndex(); int layoutPosition = layoutParams.getViewLayoutPosition(); int itemCount = parent.getAdapter().getItemCount(); boolean leftEdge = spanIndex == 0; boolean rightEdge = spanIndex == (spanCount - 1); boolean topEdge = spanIndex < spanCount; boolean bottomEdge = layoutPosition >= (itemCount - spanCount); int halfSpacing = spacing / 2; outRect.set( leftEdge ? spacing : halfSpacing, topEdge ? spacing : halfSpacing, rightEdge ? spacing : halfSpacing, bottomEdge ? spacing : 0 ); } } } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.