包装布局上的 GridLayoutManager 不会调整 RecyclerView 的大小来显示项目

GridLayoutManager on a wrapped layout does not size up the RecyclerView to display the items

RecyclerViewwrap_contentGridLayoutManager 不显示项目。它不会放大来为物品腾出空间。

首先,我注意到there is an issue (74772) open for it, but it isn't solved yet as of December 2015, and not until “early 2016”

似乎有人制作了这个 CustomGridLayoutManager, also available on Github,但它似乎仍然没有为所有项目腾出足够的空间,使得 RecyclerView 看起来被裁剪(但可滚动),即使有足够的空间RecyclerView 在其父项中的空间。

关于如何使 RecyclerView 正确调整项目大小并在不滚动的情况下显示它的任何想法,如果可能的话?

class 似乎在测量时仅考虑第一个子项和每行的第一个子项(分配的维度取决于方向)。看到这个(我的评论):

if (getOrientation() == HORIZONTAL) {
    if (i % getSpanCount() == 0) { // only for first child of row.
        width = width + mMeasuredDimension[0];
    }
    if (i == 0) { // only for first item.
        height = mMeasuredDimension[1];
    }
}

方向 VERTICAL 发生了相同的事情(在随后的 else 中发现)。

为了满足我的需求,我测量了每个子项,检查每行中最大的子项,然后将最大约束应用于该行。完成对每一行的测量后,将行大小添加到所需的总大小中。

if (getOrientation() == VERTICAL) {
    rowMeasure[1] = Math.max(rowMeasure[1], childMeasure[1]);
    rowMeasure[0] += childMeasure[0];
} else {
    rowMeasure[0] = Math.max(rowMeasure[0], childMeasure[0]);
    rowMeasure[1] += childMeasure[1];
}

// When finishing the row (last item of row), adds the row dimensions to the view.
if (i % getSpanCount() == getSpanCount() - 1 || i == state.getItemCount() - 1) {
    rowsSized[addIndex] += rowMeasure[addIndex];
    rowsSized[maxIndex] = Math.max(rowsSized[maxIndex], rowMeasure[maxIndex]);
    rowMeasure[addIndex] = 0;
    rowMeasure[maxIndex] = 0;
}

完整的 class 可以在这个答案的末尾找到。以上只是逻辑。

我还没有完全测试这个解决方案,因为我这周遇到了这个问题,并试图在昨天(12 月 8 日)再次解决它,至少是为了我的需要。

你可以看看我是如何用我的 WrappedGridLayoutManager here.

解决这个问题的

如问题评论中所述,您必须注意 RecyclerViewState,而不是使用其 getItemCount()。我还建议查看 getViewForPosition(int) 以查看 if/how 这可能会受到预布局条件等的影响。