Как стать автором
Обновить

Комментарии 6

Подождите, при чем тут recycling? Это внутренние детали реализации, они вообще интересовать не должны. У вас есть событие onViewAttachedToWindow – в нем можно навесить listener, есть onViewDetachedFromWindow – в нем убрать listener. Почему вы вообще listener навешиваете в onBindViewHolder? Он же может несколько раз вызваться для одного и того же элемента, если в нем что-то поменялось.

Во-первых, я совершенно не претендую на знание истины в последней инстанции. Во-вторых, по-существу вопроса: метка утилизатора в коллекции данных для адаптера позволяет избежать ненужного повтора выполнения кода, хоть в методе onBindViewHolder, хоть в методах onViewAttachedToWindow и onViewDetachedFromWindow. Это имеет смысл тогда, когда код слушателей «весит» больше, чем метка с кодом её проверки, или когда в коде необходима позиция элемента списка. Возможно, есть ещё какие-нибудь варианты.

Дело не в "весе" слушателей, дело в самом подходе. Завязываться на recycling неправильно, потому что он не имеет никакого отношения к жизненному циклу самого view.


Как один из вариантов: представьте, что дефолтная реализация recycling'а изменилась (или кто-то изменил ее в проекте для оптимизации производительности), и теперь в кэше хранится 100 элементов. Вы не убираете слушателей в onViewDetachedFromWindow, поэтому они будут продолжать выполняться для всех 100 элементов, хотя их уже нет в списке.


Кроме того, зачем вообще усложнять код какими-то флагами? Есть вполне определенные события onViewAttachedToWindow и onViewDetachedFromWindow. Какая разница, сохраняется ли view в кэше, если его нет на экране и взаимодействовать с ним не надо?

Во-первых, мне не ясно, почему вы считаете, что метод onViewRecycled() не имеет отношения к жизненному циклу вью? Ведь согласно этому документу это не так. Во-вторых, видимо, я не очень внятно в заметке обратил внимание на то, что я НЕ предлагаю менять реализацию жизненного цикла вью. Я предлагаю учитывать порядок обращения ОС к методам обратного вызова, одним из которых является onViewRecycled(). В-третьих, разница в том в каком кэше сохраняется вью как раз-таки и есть, потому, что в одном случае производится вызов метода onCreateViewHolder() и, следом, onBindViewHolder(), а в другом — нет.
Безусловно, есть случаи, когда эта разница не актуальна. Но есть случаи, когда она важна. Например, когда в слушателе необходимо учитывать позицию элемента в списке, доступ к которой есть в методе onBindViewHolder() и отсутствует в onViewAttachedToWindow()

Ответил статьей.

Можно расширить класс данных на булевое поле (назовем его, например, isSelected, по умолчанию равное false.
При изменении чекбокса меняется значение isSelected.
Само значение чекбокса ставится в зависимости от значения isSelected.
И тогда не нужно заморачиваться с жизненным циклом: мы не потеряем наши чекбоксы.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации