【问题标题】:Changing number of columns in RecyclerView gridlayout更改 RecyclerView 网格布局中的列数
【发布时间】:2015-01-02 15:55:22
【问题描述】:

我正在尝试根据显示大小更改回收站视图(网格布局)中显示的列数。但是我无法找到实现它的正确方法。目前我正在使用treeViewObserver 根据屏幕尺寸的变化(在方向期间)更改列数。因此,如果应用程序以纵向模式打开,则(在手机上)它决定为一列,这看起来不错,但是当应用程序直接以横向模式打开时,此方法不起作用,其中网格中有一张拉伸的卡片显示在屏幕上。

这里的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();

最好的问候

【问题讨论】:

  • 你有办法解决这个问题吗?

标签: android gridlayoutmanager


【解决方案1】:
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);
}}

【讨论】:

  • 优秀的答案!刚刚在我的项目中使用了这个类,它工作得很好:)
  • 这里的宽度单位是多少?像素还是DP?我觉得是像素,加上dp转换会更有用
  • @AbdulMuhaymin 虽然你是对的,但我们使用的是返回像素的方法 LayoutManager.getWidth()。 developer.android.com/reference/android/support/v7/widget/…
【解决方案2】:

如果您提供固定的列宽,您可以扩展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

【讨论】:

  • 列宽不固定怎么办。
【解决方案3】:

这是我的解决方案。

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
【解决方案4】:

您可以创建一个依赖于屏幕的资源文件并加载它。例如 values-w820p 文件夹中的 booleans.xml。或者可能只是为大屏幕创建一个布局并完成它。

【讨论】:

    猜你喜欢
    • 2019-08-06
    • 1970-01-01
    • 2021-03-25
    • 1970-01-01
    • 1970-01-01
    • 2019-09-29
    • 1970-01-01
    • 2018-05-08
    • 1970-01-01
    相关资源
    最近更新 更多