Горизонтальный 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());
}
}
- Сохранение
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
зависимость для проекта