2015-01-02 2 views
15

Sto cercando di modificare il numero di colonne visualizzate nella vista del riciclatore (layout della griglia) in base alle dimensioni dello schermo. Tuttavia non sono riuscito a trovare un modo adeguato per raggiungerlo. Al momento sto utilizzando treeViewObserver per modificare il numero di colonne in base alla modifica delle dimensioni dello schermo (durante l'orientamento). Quindi, se l'app si apre in modalità verticale, il numero di colonne (sul telefono) decide di esserlo, il che sembra buono, ma questo metodo non funziona quando l'app si apre direttamente in modalità orizzontale, dove una singola scheda streched nella griglia viene visualizzato sullo schermo.Modifica del numero di colonne in RecyclerView gridlayout

Qui recList è RecyclerView & glm è GridLayoutManager utilizzato in RecyclerView

viewWidth = recList.getMeasuredWidth(); 

    cardViewWidthZZ = recList.getChildAt(0).getMeasuredWidth(); 

    if (oldWidth == 0) { 
     oldWidth = cardViewWidthZZ; 
    } 

    if (oldWidth <= 0) 
     return; 

    int newSpanCount = (int) Math.floor(viewWidth/(oldWidth/1.3f)); 
    if (newSpanCount <= 0) 
     newSpanCount = 1; 
    glm.setSpanCount(newSpanCount); 
    glm.requestLayout(); 

migliori saluti

+0

Eri in grado di capire una soluzione per questo. – Shubham

risposta

28
public class VarColumnGridLayoutManager extends GridLayoutManager { 

private int minItemWidth; 

public VarColumnGridLayoutManager(Context context, int minItemWidth) { 
    super(context, 1); 
    this.minItemWidth = minItemWidth; 
} 

@Override 
public void onLayoutChildren(RecyclerView.Recycler recycler, 
     RecyclerView.State state) { 
    updateSpanCount(); 
    super.onLayoutChildren(recycler, state); 
} 

private void updateSpanCount() { 
    int spanCount = getWidth()/minItemWidth; 
    if (spanCount < 1) { 
     spanCount = 1; 
    } 
    this.setSpanCount(spanCount); 
}} 
+1

Ottima risposta! Ho appena usato questa classe nel mio progetto e funziona perfettamente :) –

+1

Questo è brillante, funziona anche per il mio progetto :) – Bruce

+0

Qual è l'unità di larghezza qui? Pixel o DP? Penso che sia pixel, aggiungendo la conversione dp diventerà più utile –

15

Se si fornisce una larghezza di colonna fissa, è possibile estendere RecyclerView e impostare il conteggio arco in onMeasure conseguenza :

public AutofitRecyclerView(Context context, AttributeSet attrs) { 
    super(context, attrs); 

    if (attrs != null) { 
    // Read android:columnWidth from xml 
    int[] attrsArray = { 
     android.R.attr.columnWidth 
    }; 
    TypedArray array = context.obtainStyledAttributes(attrs, attrsArray); 
    columnWidth = array.getDimensionPixelSize(0, -1); 
    array.recycle(); 
    } 

    manager = new GridLayoutManager(getContext(), 1); 
    setLayoutManager(manager); 
} 

protected void onMeasure(int widthSpec, int heightSpec) { 
    super.onMeasure(widthSpec, heightSpec); 
    if (columnWidth > 0) { 
    int spanCount = Math.max(1, getMeasuredWidth()/columnWidth); 
    manager.setSpanCount(spanCount); 
    } 
} 

Se e il mio post sul blog per ulteriori informazioni: http://blog.sqisland.com/2014/12/recyclerview-autofit-grid.html

+0

Cosa succede se la larghezza della colonna non è fissa. – Shubham

0

È possibile creare un file di risorse dipendente dallo schermo e caricarlo. Ad esempio, booleans.xml nella cartella values-w820p. O forse basta creare un layout per schermi di grandi dimensioni e farlo con esso.

1

Ecco la mia soluzione.

public class ResponsiveGridLayoutManager extends GridLayoutManager { 
    boolean hasSetupColumns; 
    int columnWidthPx; 

    public ResponsiveGridLayoutManager(Context context, int orientation, 
     boolean reverseLayout, int columnWidthUnit, float columnWidth) { 

     super(context, 1, orientation, reverseLayout); 

     Resources r; 
     if (context == null) { 
      r = Resources.getSystem(); 
     } else { 
      r = context.getResources(); 
     } 

     float colWidthPx = TypedValue.applyDimension(columnWidthUnit, 
      columnWidth, r.getDisplayMetrics()); 

     this.columnWidthPx = Math.round(colWidthPx); 
    } 

    public ResponsiveGridLayoutManager(Context context, AttributeSet attrs, 
     int defStyleAttr, int defStyleRes) { 

     super(context, attrs, defStyleAttr, defStyleRes); 
     int[] requestedValues = { 
      android.R.attr.columnWidth, 
     }; 

     TypedArray a = context.obtainStyledAttributes(attrs, requestedValues); 
     this.columnWidthPx = a.getDimensionPixelSize(0, -1); 
     a.recycle(); 
    } 

    @Override 
    public int getWidth() { 
     int width = super.getWidth(); 
     if (!hasSetupColumns && width > 0) { 
      this.setSpanCount((int)Math.floor(width/this.columnWidthPx)); 
     } 

     return width; 
    } 
} 

Si può usare sia con XML:

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

    app:layoutManager="com.caff.localflix.ResponsiveGridLayoutManager" 
    android:columnWidth="148dp" /> 

o Java:

ResponsiveGridLayoutManager layoutManager = new ResponsiveGridLayoutManager(
    this, 
    GridLayoutManager.VERTICAL, 
    false, 
    TypedValue.COMPLEX_UNIT_DIP, 
    148f 
);