9

Je souhaite créer un espace entre les éléments de la grille. Les articles doivent tous avoir la même largeur/hauteur.Appliquer le décalage aux éléments GridLayout et conserver la même taille parmi tous les éléments

Ce que j'ai essayé:

Créer une GridLayoutOffsetDecorator qui applique un décalage à tous les éléments de la grille:

class GridLayoutOffsetDecorator(var offset: Int) : RecyclerView.ItemDecoration() { 

    override fun getItemOffsets(
      outRect: Rect, 
      view: View, 
      parent: RecyclerView, 
      state: RecyclerView.State?) { 

     super.getItemOffsets(outRect, view, parent, state) 

     outRect.set(offset, offset, offset, offset) 
    } 
} 

Après avoir un décalage de 8dp crée un espace 16dp entre les éléments. Nous avons donc encore à appliquer 8dp de rembourrage aux bords extérieurs:

<android.support.v7.widget.RecyclerView 
     android:id="@+id/productList" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:clipToPadding="false" 
     android:padding="8dp" /> 

Le résultat est le suivant:

enter image description here

Problème: les articles ne sont pas égaux en taille:

enter image description here

Vous remarquez une légère différence en hauteur quand vous regardez la ligne bleue. Cette différence apparaît seulement après le remplissage du recyclerview. Ce rembourrage semble légèrement redimensionner certains des éléments. Avez-vous l'expérience de ce problème? Une idée de comment cela peut être résolu? En supprimant l'image des éléments, la différence de hauteur disparaît. Voici comment l'image est définie:

<SquareImageView 
    android:id="@+id/image" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:scaleType="centerCrop" 
    app:imageResource="@{product.image}" /> 

SquareImageView:

class SquareImageView : ImageView { 

    constructor(context: Context) : super(context) 
    constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet) 
    constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr) 

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 
     super.onMeasure(widthMeasureSpec, widthMeasureSpec) 
    } 
} 

Le problème peut être causé par l'image elle-même.

+0

D'où proviennent les différences de hauteur? Y at-il une différence dans tous vos articles, ou est-ce que l'article à l'indice 0 est plus élevé que tous les autres? – W3hri

+0

@ W3hri la différence de hauteur est dans un ou deux éléments, mais jamais dans la totalité, la position des éléments affectés est aléatoire –

+0

Ma première supposition était que peut-être le ImageView, qui ressemble à son ensemble à recadrer, provoque des problèmes. Cela arrive-t-il aussi sur les éléments en texte seul? – W3hri

Répondre

2

J'ai eu le même problème lorsque je travaillais avec GridLayoutManager. Résolu en définissant la largeur et la hauteur de l'image dans l'adaptateur. Voici ma solution, j'espère que ça aidera.

C'est comme ça que j'ai placé ImageView dans mon layout.

<LinearLayout 
    android:id="@+id/layoutImageProduct" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:gravity="center" 
    tools:minHeight="100dp" 
    tools:minWidth="150dp"> 

     <ImageView 
      android:id="@+id/imageProduct" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:scaleType="fitCenter" 
      android:src="@drawable/placeholder_product"/> 
</LinearLayout> 

Et puis appliquez LayoutParams sur la disposition des parents et ImageView

//Setting View width/height 
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) holder.layoutImageProduct.getLayoutParams(); 
params.width = (int) ResourcesUtils.getColumnWidth(context); 
params.height = ((int) (ResourcesUtils.getColumnWidth(context))); 
holder.layoutImageProduct.setLayoutParams(params); 

params = (LinearLayout.LayoutParams) holder.imageProduct.getLayoutParams(); 
params.width = (int) ResourcesUtils.getColumnWidth(context); 
params.height = (int) ResourcesUtils.getColumnWidth(context); 
holder.imageProduct.setLayoutParams(params); 

est ici la méthode getWidth.

public static float getColumnWidth(Context context) { 
     if (GRID_COLUMN_WIDTH == -1) { 
      int screenWidth = getDisplayMetrics(context).widthPixels; 
      float horizontalPadding = getDimensInPixel(context, R.dimen.activity_horizontal_margin); 
      // NUM OF COLUMN = 2 
      GRID_COLUMN_WIDTH = screenWidth/2 - horizontalPadding * 2; 
     } 

     return GRID_COLUMN_WIDTH; 
    } 

Voir la capture d'écran, une avec marque de réservation et une avec image. One with placeholder and one with image.

+0

Eh bien merci, un peu hacky mais ça va totalement résoudre le problème. –

+0

Oui, il sera, vous êtes les bienvenus. –

1

Pouvez-vous s'il vous plaît essayer avec la hauteur de l'image comme fixe.