2015-08-18 14 views
6

Definisco il mio RecyclerView come griglia impostandone il layout con GridLayoutManger che ha un conteggio span di 3 che funzionano già correttamente. Aggiungo anche un decoratore di oggetti alla mia vista del riciclatore che gestirà la spaziatura tra gli elementi della griglia, anche questo funziona bene.Come rendere l'elemento griglia di RecyclerView per avere uguale altezza e larghezza?

public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration { 

    private int spanCount; 
    private int spacing; 
    private boolean includeEdge; 

    public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) { 
     this.spanCount = spanCount; 
     this.spacing = spacing; 
     this.includeEdge = includeEdge; 
    } 

    @Override 
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 
     int position = parent.getChildAdapterPosition(view); // item position 
     int column = position % spanCount; // item column 

     if (includeEdge) { 
      outRect.left = spacing - column * spacing/spanCount; // spacing - column * ((1f/spanCount) * spacing) 
      outRect.right = (column + 1) * spacing/spanCount; // (column + 1) * ((1f/spanCount) * spacing) 

      if (position < spanCount) { // top edge 
       outRect.top = spacing; 
      } 
      outRect.bottom = spacing; // item bottom 
     } else { 
      outRect.left = column * spacing/spanCount; // column * ((1f/spanCount) * spacing) 
      outRect.right = spacing - (column + 1) * spacing/spanCount; // spacing - (column + 1) * ((1f/ spanCount) * spacing) 
      if (position >= spanCount) { 
       outRect.top = spacing; // item top 
      } 
     } 
    } 
} 

mio implementazione per l'aggiunta di decorazione oggetto ai miei Recycler Vista:

mBuddiesGrid = (RecyclerView) findViewById(R.id.buddies_grid); 
     mLayoutManager = new GridLayoutManager(getApplicationContext(), 3); 
     mBuddiesGrid.addItemDecoration(new GridSpacingItemDecoration(3, (int) dpToPx(10) , true)); 
     mBuddiesAdapter = new BuddiesGridAdapter(getApplicationContext(), new Buddies()); 
     mBuddiesGrid.setLayoutManager(mLayoutManager); 

La mia griglia di layout elemento xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
    android:orientation="vertical" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    xmlns:android="http://schemas.android.com/apk/res/android"> 

    <ImageView 
     android:layout_weight="1" 
     android:cropToPadding="false" 
     android:id="@+id/profile_picture" 
     android:scaleType="centerCrop" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" /> 

    <TextView 
     android:text="Theodore" 
     android:includeFontPadding="false" 
     android:textColor="@android:color/black" 
     android:id="@+id/name" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" /> 
</LinearLayout> 

Con l'aggiunta di spazi tra voce griglia sarà regolare la larghezza dell'elemento di griglia che può eventualmente causare di non ottenere la dimensione delle proporzioni della vista dell'oggetto. Quello che voglio ottenere è ridimensionare l'altezza della mia griglia uguale alla sua larghezza in modo dinamico. Come posso farlo?

risposta

-1

È possibile scrivere il codice nella funzione "onBindViewHolder" nel supporto visualizzazione riciclatore. In questo modo è possibile ottenere l'osservatore dell'albero delle viste del riciclatore e modificare la larghezza o (e) l'altezza della vista degli elementi del riciclatore.

+0

Utilizzando la TreeObserver è l'ultima risorsa e un soluzione hacker, utilizzando un layout personalizzato modificato è molto più pulito. Inoltre, la modifica dei layout in base all'ascolto della struttura del layout potrebbe comportare più passaggi di layout. –

2

Un modo per garantire la stessa larghezza/altezza è utilizzare una vista personalizzata che calcola l'altezza in base alla larghezza quando viene chiamato onMeasure(). La cosa bella con questo è che oltre a creare la vista personalizzata, non è coinvolto alcun codice.

Ecco una visualizzazione personalizzata che si estende LinearLayout:

public class SquareLayout extends LinearLayout { 

    public SquareLayout(Context context) { 
     super(context); 
    } 

    public SquareLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public SquareLayout(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    @Override 
    protected void onMeasure(int width, int height) { 
     // note we are applying the width value as the height 
     super.onMeasure(width, width); 
    } 

} 

Ecco una versione alterata del layout oggetto griglia, utilizzando il sopra personalizzato LinearLayout:

<com.yourpackage.name.views.SquareLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 

    <ImageView 
     android:id="@+id/profile_picture" 
     android:layout_width="match_parent" 
     android:layout_height="0dp" 
     android:layout_weight="1" 
     android:cropToPadding="false" 
     android:scaleType="centerCrop" /> 

    <TextView 
     android:id="@+id/name" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:includeFontPadding="false" 
     android:textColor="@android:color/black" 
     android:text="Theodore"/> 

</com.yourpackage.name.views.SquareLayout>