GridLayoutManager в упакованном макете не изменяет размер RecyclerView для отображения элементов

RecyclerView с wrap_content а также GridLayoutManager не отображает элементы. Он не увеличивается, чтобы освободить место для предметов.

Прежде всего, я заметил, что есть проблема (74772), открытая для нее, но она еще не решена по состоянию на декабрь 2015 года, и не раньше "начала 2016 года".

Кто-то, кажется, сделал это CustomGridLayoutManager также доступна на Github, но она все еще не дает достаточно места для всех предметов, делая RecyclerView выглядят обрезанными (но прокручиваемыми), даже если для RecyclerView в его родителя.

Любые идеи о том, как сделать RecyclerView правильно оценивать элементы и показывать их без прокрутки, когда это возможно?

1 ответ

Решение

Этот класс, кажется, учитывает при измерении только первый дочерний элемент и первый дочерний элемент каждой строки (какой бы размер не был назначен, зависит от ориентации). Смотрите это (комментарии от меня):

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

Полный класс доступен в конце этого ответа. Выше показана только логика.

Я еще не полностью протестировал это решение, поскольку столкнулся с этой проблемой на этой неделе и попытался решить ее - опять же, по крайней мере, для моих нужд - вчера (декабрь 08).

Вы можете проверить, как я решил эту проблему с моим WrappedGridLayoutManager здесь

Как указано в комментариях к проблеме, вы должны обратить внимание на RecyclerView "s State, используя его getItemCount() вместо. Я также рекомендую взглянуть на getViewForPosition(int) чтобы увидеть, если / как это может быть затронуто условиями предварительного просмотра и так далее.

Другие вопросы по тегам