Найти тему

ViewBinding. Переход с синтетиков

В Kotlin 1.4.20 появилось изменение Deprecation of the kotlin-android-extensions compiler plugin. Parcelable implementation generator has moved to the new kotlin-parcelize plugin — это означает, что теперь мы не можем использовать синтетический сахар и он устарел. Почти все раньше использовали синтетики и теперь приходится окончательно от них уходить. Это сделать достаточно просто, но немного скучно. Особенно в больших проектах на это унылое занятие уйдет несколько дней.

Немного интересностей, зачем и почему так сделали. Многое объясняет картинка:

Взяла здесь https://habr.com/ru/post/467295/. И сама статья хорошая.
Взяла здесь https://habr.com/ru/post/467295/. И сама статья хорошая.

Все сводится к достаточно простой вещи: при включении viewBinding, будет сгенерирован отдельный binding-файл для каждой xml, если мы не указали, что так не надо делать. Там будут все ссылки на вью, у которых есть id.

Для начала надо поднять версию gradle до 4.1.0, чтобы можно было использовать viewBinding.

Добавляем в gradle для модуля (НЕ для всего проекта)

buildFeatures { viewBinding true }

Синхронизируем и можно дальше использовать. Если после поднятия до 4.1.0 сыпятся ошибки, то попробуйте в gradle-wrapper.properties указать версию 6.5, а потом очистить кэш и снова синхронизировать. Мне помогло.

Теперь можем использовать. Если для какого-то xml не нужно генерировать файл, то указываем там tools:viewBindingIgnore="true" для корневого layout.

На примере активити:

  1. Смотрим название xml для активити. Например: activity_main.xml. Значит название будет ActivityMainBinding. Если my_awesome_activity.xml, то MyAwesomeActivityBinding. Т.е. все слова в camelCase + в конце добавляем Binding.
  2. В самой активити объявляем ActivityMainBinding и инициализируем в onCreate. А setContentView(R.layout.activity_main) заменяем на setContentView(binding.root). Готово. Теперь можем обращаться ко всем вьюшкам из xml через binding.viewName
-2

C фрагментами почти аналогично:

  1. Также смотрим название в xml и аналогично инициализируем, но только в onCreateView.
-3

Тут есть небольшое отличие. Так как фрагменты продолжают жить даже когда вью уже нет, то было бы неплохо очищать все ссылки в onDestroyView. И есть второй способ для фрагментов, который мне больше нравится: инициализация в onViewCreated. Просто потому что я обычно всегда передаю layout в конструктор фрагмента. Тут все равно надо не забыть очистить в onDestroyView.

-4

И еще один способ мне подсказали в комментариях. Способ, который советует гугл: https://developer.android.com/topic/libraries/view-binding?hl=he#fragments. И я думаю, что он мне нравится больше всего. Мы объявляем некую var и инициализируем в onViewCreated. И объявляем val binding, которая будет доступна только между onCreateView и onDestroyView. NPE не будет, потому что мы инициализируем в get, а обращение ко всем вью уже будет после onViewCreated, где мы проинициализировали _binding.

-5

Также можно использовать и в RecyclerView. Правда я не пробовала, но в интернете множество статей, которые помогут.