1

Здесь идет речь о "разумном выборе" места обработки клика в recyclerview. 1. в ViewHolder 2. в onBindViewHolder 3. с помощью интерфейса пробросить обработку в активити.

У меня вопрос: от чего зависит выбор?

Evgeny GooDi
  • 143
  • 1
  • 10

1 Answers1

0

По большей части, наверное, этот вопрос касается архитектурных решений. Но приведу пример: у вас есть список в адаптере (приватное поле класса), в котором хранится информация о элементах списка, которые будут отображены на экране.

Если у вас всё простенько и примитивненько, то вам не понадобится никакой сложной логики, вы просто будете устанавливать текст и прочее на элементы, и всё будет хорошо.

Но допустим, что у вас более сложная логика, вам нужно хранить в списке ещё и какую-то другую информацию, которая будет жестко привязана к элементам списка в ресайклере, но которая не будет отображаться на экране. Как пример - у вас есть новостная лента, в ней каждая запись имеет уникальный идентификатор, по которому вы можете получить более полную информацию о записи. Он не показывается на экране, а при нажатии на новость в ленте вам нужно открыть новое активити/показать другой фрагмент и т.д., на котором будет эта же запись, но более подробно описанная. И вот эти подробности нужно получить как раз по уникальному идентификатору записи. Откуда его взять? Проще всего, из того же списка в адаптере. Потому будет удобнее поместить обработку нажатий как раз в адаптер в метод onBindViewHolder.

Чтобы не пробрасывать через коллбэк обработку в активити (ведь приложение может быть сложным и большим, и тащить коллбэк через 15 классов будет глупо), можно использовать свои какие-то решения, или же готовые вроде rxjava или eventbus.

  • Насколько я понял, в случае если по клику открыть новую активити с подробностями кликнутого айтема, то лучше это сделать в onBindViewHolder. В каких же случаях логично обрабатывать клик в активити или ViewHolder'е? – Evgeny GooDi Sep 22 '17 at 17:40
  • @EvgenyGooDi опять же, если нет никакой сложной логики, и обработка нажатия не зависит от того, на какой именно элемент списка нажали, то можно поместить обработку в сам класс вью холдера. Обработка, которая будет настроена там, почти всегда (если не писать что-то по своему) будет одинаковой для каждого элемента списка. В адаптере же передается и сам вью холдер, и позиция элемента, а значит обработку можно к этой позиции привязать – Peter Samokhin Sep 22 '17 at 17:42
  • не понял последнее предложение – Evgeny GooDi Sep 22 '17 at 17:44
  • @EvgenyGooDi в методе onBindViewHolder два параметра - сам вью холдер и позиция элемента, верно? Так вот, для этого вью холдера вы сначала устанавливаете текст, картинки и прочее, в зависимости от его позиции. Вы же не устанавливаете текст в самом вью холдере? А почему? Потому что настройка его будет зависеть от его позиции в списке. Тоже самое и с обработкой нажатий. – Peter Samokhin Sep 22 '17 at 17:46
  • Я делаю вывод что в onBindViewHolder делать надо обработку. Там есть доступ и к элементам и к данным, которые отображать. Я сейчас пытаюсь понять как получить доступ к вью в кликнутом айтеме, если обработка клика делается в активити. И никак не пойму. Отчаяние, грусть и тоска, в общем ;) – Evgeny GooDi Sep 22 '17 at 17:49
  • @EvgenyGooDi так я же описал в конце своего ответа - попробуйте написать свой обработчик, который будет это делать. Или, что проще, используйте EventBus от Greenrobot - крайне прост в использовании, и тащить коллбэки через кучу классов не нужно. – Peter Samokhin Sep 22 '17 at 17:50
  • а можно ли как то в активити передать, скажем, id кликнутого айтема, но как тогда изменить, например, видимость вью в этом айтеме?.. – Evgeny GooDi Sep 22 '17 at 17:53
  • @EvgenyGooDi тогда держите: https://github.com/greenrobot/EventBus . В активити в методах onStart и onStop подписываетесь/отписываетесь от получения "обновлений", в нём же добавляете метод onEvent с нужной аннотацией и входными параметрами. А в адаптере вызываете bus.post(new MyEvent("some_data")) и всё. Проще некуда. – Peter Samokhin Sep 22 '17 at 17:55
  • ушел учить матчасть ;) – Evgeny GooDi Sep 22 '17 at 17:55
  • @EvgenyGooDi как передать айди кликнутого айтема, я описал чуть выше. А вот изменять видимость и всю прочую обработку ui проводите в адаптере сразу же. – Peter Samokhin Sep 22 '17 at 17:55
  • @EvgenyGooDi если ответ решает проблему вопроса, поставьте галочку :) – Peter Samokhin Sep 22 '17 at 17:56