Измерьте Recyclerview, прежде чем он появится

В настоящее время у меня возникает проблема при измерении recyclerView до его появления. Мне нужна измеренная высота, чтобы запустить анимацию «расширения».

Ранее это было сделано для gridView в коде, над которым я работаю, и я пытаюсь перенести его в RecyclerView с помощью GridLayoutManager.

final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
final int heightSpec = View.MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK, View.MeasureSpec.AT_MOST);
mGridView.measure(widthSpec, heightSpec);
int targetHeight = mGridView.getMeasuredHeight();

Он работал с gridView, но если я вызываю метод измерения с теми же спецификациями измерения в recyclerView, результатом всегда будет 16777215, что, я думаю, может быть максимальным значением для чего-то, но я не могу сказать, что.

Я видел какой-то пост, объясняющий, что представление можно измерить до того, как оно будет отображено на экране, путем измерения его со следующими спецификациями измерения:

final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
final int heightSpec = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);

но я получаю 0 для recyclerView.getMeasuredHeight();.

Есть ли способ правильно измерить высоту recyclerView до того, как он будет отображаться на экране?

Спасибо.


person Loïc    schedule 22.10.2014    source источник


Ответы (3)


Вы пытаетесь измерить представление перед его добавлением? Если да, то это опасно.

Кроме того, с точки зрения RecyclerView, к сожалению, существующие менеджеры компоновки еще не поддерживают WRAP_CONTENT. Они полагаются на базовую реализацию, которая поддерживает match_paren и точные размеры.

Если вы знаете высоту своего элемента, вы можете расширить GridLayoutManager, переопределить onMeasure и измерить его там самостоятельно.

person yigit    schedule 22.10.2014
comment
Спасибо за Ваш ответ. Отсутствие поддержки WRAP_CONTENT может объяснить проблему. Очевидно, кто-то сообщил об этом: code.google.com/p/android/issues. /detail?id=74772& . Представление создается из файла макета xml, поэтому оно добавляется в иерархию представлений. К сожалению, я не знаю рост детей, так как у меня есть несколько адаптеров, которые можно передать в recyclerView, и они могут отображать разные элементы. Я предполагаю, что если бы я мог получить макет, используемый для элемента, я мог бы надуть его, измерить, а затем вычислить высоту gridLayoutManager. Я это попробую. - person Loïc; 23.10.2014
comment
Я видел, что вы уже исправили проблему. Если вам нужно универсальное решение, вы также можете позволить первому проходу измерения занять все пространство, затем запросить другой макет, а при следующем проходе измерения вы можете вернуть координату последнего дочернего элемента (getDecoratedEnd(view)). Вы можете сделать это, просто проверив количество представлений в вызове onMeasure, может быть достаточно, если размер адаптера всегда больше 0. Надеюсь, мы получим это в следующих выпусках. - person yigit; 23.10.2014
comment
К сожалению, когда я впервые вызываю свой метод расширения, где мне нужно измерить представление, я просто создал и заполнил адаптер. Когда я хочу получить какой-либо дочерний вид, recyclerview не содержит дочерних элементов. Я предполагаю, что он должен нарисовать себя хотя бы один раз, чтобы иметь ссылки на дочерние представления? - person Loïc; 25.10.2014

Благодаря сообщению yigit я наконец-то смог вычислить будущую высоту recyclerView, вручную раздув дочернее представление, измерив его с помощью:

final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
final int heightSpec = View.MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK, View.MeasureSpec.AT_MOST);

И, наконец, умножение его измеряемой высоты на количество строк, содержащихся в gridLayoutManager. Надеемся, что скоро появится поддержка WRAP_CONTENT для менеджеров макетов RecycleViews.

person Loïc    schedule 23.10.2014