Обходной путь для измерения высоты RecyclerView с горизонтальным LinearLayoutManager - PullRequest
0 голосов
/ 29 октября 2019

Проблема

Я хочу иметь RecyclerView с width = match_parent и height = wrap_content . Мне нужно отображать элементы по горизонтали, поэтому я использую правильный LinearLayoutManager.

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

Исследования

Я видел несколько старых вопросов из 2016 года, когда у людей возникали некоторые похожие проблемы. Большинство решений рекомендует обновить версию recyclerView до 'com.android.support: recyclerview-v7: 23.2.1' . Но в настоящее время мы используем Androidx. Текущая стабильная версия для recyclerView: 1.0.0 Я пытался 1.1.0-rc1 , но получил тот же результат.

Также я пытался setAutoMeasureEnabled(true) для моего LinearLayoutManager, но он также не работает.

Мой обходной путь

Итак, в конце концов я попытался обновить представление ViewHolder не напрямую, присваивая значения TextViews,но через view.post (Runnable {}). И это работает, я не знаю точно, почему.

Не работает пример GIF

Рабочий пример GIF - с помощью view.post (Runnable{})

Ожидаемое поведение отображается во втором GIF-файле: как только мы прокручиваем до элемента с большим содержимым, размер представления обновляется и высота recyclerView также обновляется.

Мой вопрос

Считаете ли вы, что вышеуказанный обходной путь приемлем? Может быть, у вас есть более разумные идеи / подходы? Спасибо за помощь и внимание.

main_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#C5C510" />

</FrameLayout>

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="200dp"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/itemTextView1"
        android:layout_width="match_parent"
        android:textSize="40dp"
        tools:text="dsgsdfgsdf"
        android:gravity="center"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/itemTextView2"
        android:layout_width="match_parent"
        android:textSize="40dp"
        tools:text="dsgsdfgsdf"
        android:gravity="center"
        android:visibility="gone"
        android:layout_height="wrap_content"/>


    <TextView
        android:id="@+id/itemTextView3"
        android:layout_width="match_parent"
        android:textSize="40dp"
        tools:text="dsgsdfgsdf"
        android:gravity="center"
        android:visibility="gone"
        android:layout_height="wrap_content"/>

</LinearLayout>

MainActivity

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity)

        recyclerView.layoutManager =
            LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
        recyclerView.adapter = Adapter(100) // 100 is the number of items to be displayed, adapter generates them
    }
}

Фрагмент адаптера (по умолчанию, не работает должным образом):

    override fun onBindViewHolder(holder: ViewHolder, pos: Int) {
        holder.itemView.itemTextView1.text = "String  \n" + pos.toString()
        holder.itemView.itemTextView2.text = "String  \n" + pos.toString()
        holder.itemView.itemTextView3.text = "String  \n" + pos.toString()

        holder.itemView.itemTextView2.visibility = if (pos > 10) View.VISIBLE else View.GONE
        holder.itemView.itemTextView3.visibility = if (pos > 30) View.VISIBLE else View.GONE
    }

Фрагмент адаптера (делаетRecyclerView работает как положено):

    override fun onBindViewHolder(holder: ViewHolder, pos: Int) {
        holder.itemView.post {
            holder.itemView.itemTextView1.text = "String  \n" + pos.toString()
            holder.itemView.itemTextView2.text = "String  \n" + pos.toString()
            holder.itemView.itemTextView3.text = "String  \n" + pos.toString()

            holder.itemView.itemTextView2.visibility = if (pos > 10) View.VISIBLE else View.GONE
            holder.itemView.itemTextView3.visibility = if (pos > 30) View.VISIBLE else View.GONE

        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...