RecyclerView создает ViewHolder для всех элементов одновременно

У меня есть основной RecyclerView, который содержит другие RecyclerView (назовем их subRecyclerViews). Количество subRecyclerView основано на данных, полученных с сервера. Проблема в том, что всякий раз, когда subRecyclerView собирается стать видимым, он создает ViewHolder для всех своих элементов одновременно (вместо того, чтобы создавать ViewHolder только для видимых элементов).

В моем методе MainRecyclerViewAdapter onBindViewHolder() я вызываю

subRecyclerViewAdapter.setData(data);
subRecyclerView.notifyDataSetChanged();

что приводит к задержке, поскольку subRecyclerView вызывает методы onCreateViewHolder() и onBindViewHolder() для всех своих элементов.

Версия RecyclerView, которую я использую,

com.android.support:recyclerview-v7:25.1.1

Вопрос в том, есть ли способ сообщить subRecyclerView, что ему не нужно создавать ViewHolder для элементов, которые еще не видны? Кроме того, это ошибка в RecyclerView или я что-то не так делаю?


person Mischmo    schedule 03.02.2017    source источник
comment
Использование recyclerViews вместо другого recyclerView не кажется мне хорошей идеей. В итоге у вас возникают проблемы с производительностью (например, это отставание, которое у вас есть). Помните, что вы также можете отображать списки с помощью ListViews или включать прокрутку с помощью ScrollViews.   -  person Rosário Pereira Fernandes    schedule 03.02.2017
comment
@RosárioPereiraFernandes Не могли бы вы объяснить, почему использование ListView было бы лучше, чем использование RecyclerView? Я всегда думал, что они добавили RecyclerView, потому что он был лучше оптимизирован, чем ListView. Использование ScrollView может быть лучшим способом, но есть проблема, что я не знаю, сколько SubRecyclerView будет, пока не получу данные с сервера. Также каждый из SubRecyclerView может отображать данные по-разному, некоторые из них представляют собой сетки, некоторые — горизонтальные списки или обычные вертикальные списки. Это также основано на данных с сервера.   -  person Mischmo    schedule 06.02.2017
comment
О, понятно.. Ну, основное различие между RecyclerView и ListView заключается в том, что ListViews создают все свои представления, когда вы устанавливаете адаптер. Но RecyclerViews создает только видимые представления, когда вы устанавливаете адаптер; Когда эти виды больше не видны, они уничтожаются и создаются новые видимые элементы. Вот почему я думаю, что наличие subRecyclerView может быть проблемой: вы будете создавать и уничтожать множество представлений одновременно.   -  person Rosário Pereira Fernandes    schedule 06.02.2017
comment
@RosárioPereiraFernandes Думаю, я понимаю, что вы имеете в виду, но, поскольку мой RecyclerView создает все представления одновременно, разве это не похоже на использование ListView? Также я не думаю, что RecyclerView точно уничтожает старые представления и создает новые для новых видимых элементов. Насколько я понимаю, он только перерабатывает старые представления и повторно использует их для новых элементов. И поскольку задержка возникает только тогда, когда в поле зрения появляется новый SubRecyclerView и метод onCreateViewHolder() вызывается для всех элементов SubRecyclerView одновременно, я думаю, что проблема именно в том, что он ведет себя как ListView.   -  person Mischmo    schedule 06.02.2017
comment
@Mischmo: Ты когда-нибудь мог это понять?   -  person Kevin    schedule 12.12.2017
comment
@Kevin: К сожалению, я не смог этого понять. Если вам когда-нибудь удастся найти решение, пожалуйста, опубликуйте его здесь, это будет очень признательно.   -  person Mischmo    schedule 12.01.2018


Ответы (1)


В наши дни решением вместо использования «subRecyclerViews» является использование одного recyclerView с ConcatAdapter.

val firstAdapter: FirstAdapter
val secondAdapter: SecondAdapter
val thirdAdapter: ThirdAdapter
val concatAdapter = ConcatAdapter(firstAdapter, secondAdapter, 
     thirdAdapter)
recyclerView.adapter = concatAdapter
person MSpeed    schedule 10.11.2020