Что хранит ViewHolder в RecyclerView: визуальные элементы или данные
Что проверяют
Понимаете ли вы механику переиспользования в RecyclerView: один и тот же ViewHolder за время прокрутки показывает десятки разных элементов. Следом обычно спрашивают, где хранить состояние элемента, например отмеченный чекбокс, и как правильно обработать клик.
Как отвечать
Короткий ответ: ViewHolder хранит визуальную часть, а не данные. Внутри у него:
itemViewи ссылки на дочерние view или объектViewBinding: их находят один раз вonCreateViewHolder(), чтобы не зватьfindViewById()при каждой привязке;- служебные поля
RecyclerView: тип view, позиция,itemId, флаги состояния. Позицию берут черезbindingAdapterPosition(сConcatAdapterона отличается отabsoluteAdapterPosition), старыйadapterPositionпомечен устаревшим.
Жизненный цикл: onCreateViewHolder() создаёт холдер и разметку, onBindViewHolder() заливает в него данные конкретной позиции. Ушедший с экрана холдер попадает сначала в кэш, затем в RecycledViewPool (по умолчанию до пяти штук на тип view) и снова привязывается к другим данным.
Отсюда оговорка, которую стоит произнести: холдер может держать ссылку на текущий элемент, чтобы обработчику клика было что передать наружу. Но это временная ссылка, а источник правды это список в адаптере, ListAdapter с DiffUtil или состояние во ViewModel.
Где спотыкаются
Хранят состояние в самом холдере: флаг выбора, раскрытость, прогресс загрузки. После прокрутки холдер переходит к другому элементу, и отметки «прыгают» по списку.
Навешивают слушатель в onBindViewHolder() с позицией из параметра метода. После вставки или удаления элементов эта позиция устаревает, и клик уходит не туда. Слушатель лучше ставить один раз при создании холдера, а позицию читать в момент клика.
Задают view только в одной ветке условия: показывают значок у избранного элемента, но не скрывают его в else. Переиспользованный холдер приносит значок от прошлого элемента.