web-dev-qa-db-ja.com

RecyclerViewグリッドレイアウトの列数の変更

表示サイズに基づいて、リサイクラービュー(グリッドレイアウト)に表示される列の数を変更しようとしています。しかし、それを達成するための適切な方法を理解することができませんでした。現在、私はtreeViewObserverを使用して、画面のサイズの変化に基づいて(方向付け中)列数を変更しています。したがって、アプリが縦向きモードで開く場合、列の数(電話上)は1であると判断されますが、見栄えは良いですが、アプリが横向きモードで直接開くと、グリッド内の1枚のカードがストレッチされます。この方法は機能しません。画面にが表示されます。

recListはRecyclerViewで、glmはRecyclerViewで使用される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();

宜しくお願いします

16
Umer Farooq
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);
}}
29
jasxir

固定列幅を提供する場合、RecyclerViewを拡張し、それに応じてonMeasureにスパン数を設定できます。

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

詳細については、私のブログ投稿を参照してください: http://blog.sqisland.com/2014/12/recyclerview-autofit-grid.html

15
chiuki

これが私の解決策です。

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

またはJava:

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

画面に依存するリソースファイルを作成して読み込むことができます。たとえば、values-w820pフォルダー内のbooleans.xml。または、おそらく大画面のレイアウトを作成して、それで完了できます。

0
Mark Miller