2015-01-02 17 views
15

Ich versuche, die Anzahl der Spalten in der Recycler-Ansicht (Rasterlayout) basierend auf der Anzeigegröße zu ändern. Ich konnte jedoch keinen richtigen Weg finden, es zu erreichen. Im Moment verwende ich treeViewObserver, um die Anzahl der Spalten basierend auf der Änderung der Bildschirmgröße (während der Ausrichtung) zu ändern. Also, wenn die App im Hochformat öffnet, die Anzahl der Spalten (am Telefon) entscheidet, eins zu sein, die gut aussehen, aber diese Methode funktioniert nicht, wenn die App direkt im Querformat öffnet, wo eine einzelne gestreckte Karte im Raster wird auf dem Bildschirm angezeigt.Anzahl der Spalten im RecyclerView-Rasterlayout ändern

Hier recList ist RecyclerView & glm GridLayoutManager in RecyclerView

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

Mit freundlichen Grüßen

+0

Konnten Sie eine Lösung dafür herauszufinden. – Shubham

Antwort

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

Ausgezeichnete Antwort! Habe diesen Kurs einfach in meinem Projekt benutzt und es funktioniert perfekt :) –

+1

Das ist genial, funktioniert auch für mein Projekt :) – Bruce

+0

Was ist die Breiteneinheit hier? Pixel oder DP? Ich denke, es ist Pixel, Hinzufügen von dp-Konvertierung wird nützlicher –

15

Wenn Sie eine feste Spaltenbreite bereitzustellen, können Sie RecyclerView und stellen Sie die Spanne Zahl in onMeasure entsprechend erweitern :

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 mein Blogbeitrag für weitere Informationen: http://blog.sqisland.com/2014/12/recyclerview-autofit-grid.html

+0

Was ist, wenn die Spaltenbreite nicht festgelegt ist? – Shubham

0

Sie könnten eine Bildschirm abhängige Ressourcendatei erstellen und laden. Eine booleans.xml im Ordner values-w820p zum Beispiel. Oder vielleicht einfach ein Layout für große Bildschirme erstellen und damit fertig sein.

1

Hier ist meine Lösung.

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

Sie können es entweder mit XML verwenden:

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

oder Java:

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