В Kotlin 1.4.20 появилось изменение Deprecation of the kotlin-android-extensions compiler plugin. Parcelable implementation generator has moved to the new kotlin-parcelize plugin — это означает, что теперь мы не можем использовать синтетический сахар и он устарел. Почти все раньше использовали синтетики и теперь приходится окончательно от них уходить. Это сделать достаточно просто, но немного скучно. Особенно в больших проектах на это унылое занятие уйдет несколько дней.
Немного интересностей, зачем и почему так сделали. Многое объясняет картинка:
Все сводится к достаточно простой вещи: при включении 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.
На примере активити:
- Смотрим название xml для активити. Например: activity_main.xml. Значит название будет ActivityMainBinding. Если my_awesome_activity.xml, то MyAwesomeActivityBinding. Т.е. все слова в camelCase + в конце добавляем Binding.
- В самой активити объявляем ActivityMainBinding и инициализируем в onCreate. А setContentView(R.layout.activity_main) заменяем на setContentView(binding.root). Готово. Теперь можем обращаться ко всем вьюшкам из xml через binding.viewName
C фрагментами почти аналогично:
- Также смотрим название в xml и аналогично инициализируем, но только в onCreateView.
Тут есть небольшое отличие. Так как фрагменты продолжают жить даже когда вью уже нет, то было бы неплохо очищать все ссылки в onDestroyView. И есть второй способ для фрагментов, который мне больше нравится: инициализация в onViewCreated. Просто потому что я обычно всегда передаю layout в конструктор фрагмента. Тут все равно надо не забыть очистить в onDestroyView.
И еще один способ мне подсказали в комментариях. Способ, который советует гугл: https://developer.android.com/topic/libraries/view-binding?hl=he#fragments. И я думаю, что он мне нравится больше всего. Мы объявляем некую var и инициализируем в onViewCreated. И объявляем val binding, которая будет доступна только между onCreateView и onDestroyView. NPE не будет, потому что мы инициализируем в get, а обращение ко всем вью уже будет после onViewCreated, где мы проинициализировали _binding.
Также можно использовать и в RecyclerView. Правда я не пробовала, но в интернете множество статей, которые помогут.