2015-01-02 4 views
15

디스플레이 크기에 따라 리사이클 뷰 (그리드 레이아웃)에 나타나는 열 수를 변경하려고합니다. 그러나 나는 그것을 성취 할 수있는 적절한 방법을 찾아 내지 못했습니다. 현재 treeViewObserver을 사용하여 화면 크기의 변화에 ​​따라 열 수를 변경합니다 (방향 중). 그래서 앱이 세로 모드로 열리면 (전화상의) 열의 수가 1로 결정됩니다. 그러나이 방법은 앱이 가로 모드로 열릴 때 작동하지 않습니다. 가 화면에 표시됩니다.RecyclerView 그리드 레이 아웃의 열 수 변경

여기 recList는 RecyclerView & GLM가 GridLayoutManager는 고정 컬럼 폭을 제공하는 경우

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

안부

+0

이에 대한 해결책을 알아낼 당신이 할 수 있었다. – Shubham

답변

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

우수 답변! 그냥 내 프로젝트 에서이 클래스를 사용하고 완벽하게 작동합니다 :) –

+1

이것은 훌륭합니다, 내 프로젝트에도 잘 작동합니다 :) – Bruce

+0

너비 단위는 무엇입니까? 픽셀 또는 DP? 픽셀이라고 생각하면 dp 변환이 더 유용 해집니다. –

15

하면 RecyclerView 연장 따라서 onMeasure에서 스팬 횟수를 설정할 수 RecyclerView에서 사용되는 인 :

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 자세한 내용은 내 블로그 게시물을 참조하십시오. http://blog.sqisland.com/2014/12/recyclerview-autofit-grid.html

+0

열 너비가 고정되지 않으면 어떻게됩니까? – Shubham

0

화면 종속 리소스 파일을 만들고로드 할 수 있습니다. 예를 들어 값 -w820p 폴더의 booleans.xml. 또는 대형 스크린을위한 레이아웃을 만들고 그걸로 끝낼 수도 있습니다.

1

여기 내 해결책이 있습니다.

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

당신은 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" /> 

또는 자바 :

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