Горизонтальный RecyclerView с переменными высотами элементов, которые не обертываются должным образом

Что я намерен достичь

введите описание изображения здесь

Вид элемента должен занимать всю высоту элемента

введите описание изображения здесь

Возможно, высота элемента меньше высоты самого высокого элемента в recyclerview, и в этом случае он должен просто придерживаться вершины, как на скриншоте выше.

Ошибка, с которой я столкнулся

введите описание изображения здесь

Как и на скриншоте выше, просмотры становятся усеченными.

Что я пробовал до сих пор

Сначала я пошел с wrap_content на recyclerview, теперь, когда он поддерживается. Это не сработало, когда ни один из видов, видимых на экране в то время, не был самым высоким. Это имеет смысл в том, как изложена иерархия представлений. Как может быть подсчитана высота того, что еще не было привязано к каким-либо данным, если высота зависит от этих данных?

Временное решение: S

Вместо того, чтобы пытаться настроить manmanager, я сначала пошел с тем, что, как мне казалось, нужно было сделать, - сначала изложив все виды элементов, чтобы выяснить их высоту.

В верхней части экрана есть индикатор прогресса и анимация, чтобы привлечь внимание пользователя, в то время как все это происходит, когда видимость recyclerview становится невидимой. Я использую две вещи: одного недостаточно - я подключил наблюдателя к вызову адаптера onViewAttached(), и я также использовал прослушиватель изменений прокрутки. Там LinearSnapHelper подключен к просмотру ресайклера, чтобы привязать к соседнему (следующее или предыдущее, в зависимости от направления прокрутки) положение прокрутки.

В этой настройке

  • Я перехожу к каждой позиции в recyclerview, используя layoutManager.smoothScrollToPosition()
  • Получение высоты просмотра детей с помощью

            View currentChildView = binding.nextRv.getChildAt(layoutManager.findFirstCompletelyVisibleItemPosition());
            if (currentChildView != null) {
                currentChildHeight = currentChildView.getHeight();
            }
    

в прослушивателе смены прокрутки на RecyclerView.SCROLL_STATE_IDLE или передавая высоту наблюдаемому наблюдателю, упомянутому выше в адаптере onViewAttachedToWindow()

@Override
public void onViewAttachedToWindow(BindingViewHolder holder) {
    if (mObserver != null) {
        mObserver.onViewAttached(holder.binding.getRoot().getHeight());
    }
}
  1. Сохранение maxHeight, которое изменяется на max maxHeight и новую высоту ребенка.

Как видно, это уродливо. Плюс это не дает мне текущую высоту взгляда - onAttached означает, что она просто привязана, не измеряется и не выкладывается. Это переработанное представление, а не представление, связанное с текущим элементом данных. Что представляет проблемы, такие как усечение вида, показанное выше.


Я также попробовал height_content height в представлении recycler и недействителен от родителя-реципилятора до тех пор, пока ресайлер и дочерний элемент на свитке не перейдут в SCROLL_STATE_IDLE. Не работает.


Я не уверен, как может помочь пользовательский layoutmanager.

Может ли кто-нибудь вести меня в правильном направлении?

Ответ 1

Я не мог принять ответ @Pradeep Kumar Kushwaha, потому что против одного решения я не хочу, чтобы в списке были разные размеры шрифта. Консистенция является ключевым элементом в дизайне. Вторая альтернатива, которую он дал, не могла работать, потому что с эллипсисом мне нужно было бы указать кнопку "больше", чтобы пользователь мог прочитать весь контент, а мой текстовый вид уже принимает действие щелчка. Помещение в другое место еще раз не будет хорошим дизайном.

Изменение дизайна с простым компромиссом изменения размера recyclerview, когда самый высокий, усеченный элемент входит в фокус, он превращается в простой пример использования notifyItemChanged(). Даже для попытки, которую я сделал с использованием наблюдаемого наблюдателя наблюдателя и пользователя прокрутки, можно использовать notifyItemChanged, но этот подход слишком взломан. Это я могу жить как в коде, так и в дизайне. Здесь требуется код.

@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
    if (newState == RecyclerView.SCROLL_STATE_IDLE) {
        int position = ((LinearLayoutManager) binding.nextRv.getLayoutManager())
                .findFirstVisibleItemPosition();
        if (position != nextSnippetAdapter.getItemCount() - 1) {
            binding.nextRv.getAdapter().notifyItemRangeChanged(position, 2);
        } else {
            binding.nextRv.getAdapter().notifyItemChanged(position);
        }
    }
}

Для моей конкретной настройки вызывается только эти два элемента. Его можно дополнительно оптимизировать, чтобы в большинстве случаев вызвать один элемент в position + 1 и проверить и вызвать соответствующий в угловых (буквальных) случаях.

Ответ 2

Внутри адаптера, где я могу найти две карты один сверху, а другой внизу

Как бы я определил свой макет, это примерно так:

Cardview1

    LinearLayout1 --> orientation vertical

    cardview2 (Top card where text is written)

    Linearlayout2 (where I can see icons such as like etc)-->orientation horizontal

Теперь исправьте высоту Linearlayout2, установив ее для обертывания содержимого.

И высота cardview2 должна быть 0dp и добавить вес = 1

Теперь внутри cardview2 добавьте TextView1 в соответствие с высотой и шириной.

Лучше внутри textview1 добавить эллипсис в конец и добавить max lines

Если вы хотите показать все строки, попробуйте найти библиотеку autoresizetextview, здесь она может быть создана → AutoResizeTextView

Надеюсь, что это поможет.

Ответ 3

Я думаю, что просмотрщик может быть установлен на высоту wrap_content. И предметы могут быть сделаны как высота до match_parent.

<androidx.recyclerview.widget.RecyclerView
    android:layout_width="match_parent"
    android:layput_height="wrap_content"/>

Элемент как:

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

   // your coode

</androidx.constraintlayout.widget.ConstraintLayout>

У меня было немного больше требований, чем вопрос. Даже моя проблема решена в пути.

Помните, я использую:

androidx.recyclerview:recyclerview:1.0.0-beta01

зависимость для проекта