Я хочу задокументировать проблемы, с которыми я столкнулся, и решение для пользы других, и найти помощь с ключевым недостатком в моем решении.
Я хочу RecyclerView
с произвольным числом строкв макете с рядом других видов.RecyclerView
и другие View
должны быть в ScrollView
, который прокручивается, но сам RecyclerView
не должен прокручиваться.
Поскольку число строк в RecyclerView
неизвестно, иЯ должен иметь другие представления непосредственно под RecyclerView
, я не могу использовать фиксированную высоту или match_parent
.
У меня возникли странные проблемы: когда я обновляю данные RecyclerView
(используя AsyncListDiffer
) и пользовательский интерфейс должен был обновиться, весь RecyclerView
прыгнул бы выше представления, под которым он был ограничен, прямо к вершине родителя.Это не то, как ConstraintLayout
должен себя вести.
Тогда я смог остановить это, но View
под RecyclerView
исчезло бы - появившись, как только данные RecyclerView
обновлено.
Решение:
- Поместите
RecyclerView
и другие View
s внутри ConstraintLayout
внутри ScrollView
(или NestedScrollView
) - Установите для
RecyclerView
высоту wrap_content
(и добавление app:layout_constrainedHeight="true"
не повредит) - Убедитесь, что строки в RecyclerView имеют фиксированную высоту и не имеют высоты
wrap_content
Это было полезно для меня после того, как я ударился головой о стену и попробовал некоторые предлагаемые решения, которые не сработали: установите для высоты RecyclerView значение wrap_content"в макете ограничения
Это решение довольно простое.Макет может быть примерно таким:
<ScrollView
android:id="@+id/scrollView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- other Views -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/otherView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@+id/anotherView"
/>
<!-- other Views -->
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
А затем макет для строки:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="?attr/listPreferredItemHeight">
<!-- other views -->
</androidx.constraintlayout.widget.ConstraintLayout>
Вот проблема: я не фанат строк фиксированной высоты.Что, если другой контент должен войти туда?Что если пользователь изменит свой размер текста?Я предпочитаю гибкие макеты, которые могут адаптироваться к размеру.Но если я это сделаю, то RecyclerView
поднимает значение высоты экрана внутри ScrollView, выталкивая все нижние представления из нижней части экрана, независимо от того, сколько строк в нем содержится.
Альтернативы, которые яможно подумать о том, чтобы сделать все остальные View
вне RecyclerView
стать строками RecyclerView
или вообще избежать RecyclerView
и программно добавить View
s к LinearLayout
.Это гораздо более уродливые подходы.
Есть ли способ исправить это, чтобы строки RecyclerView
могли иметь высоту wrap_content
?