Иногда на собесах спрашивают что такое view binding, и звучит это как некая сложная тема, но на самом деле, это просто фича сборщика, которую можно использовать для упрощения доступа к элементам шаблонов.
Этот механизм упрощает работу с элементами пользовательского интерфейса в Android-приложениях, минимизируя ошибки, связанные с неверным использованием идентификаторов представлений (view). Он помогает избежать использования findViewById, предоставляя доступ к элементам интерфейса через сгенерированные классы.
Для начала нужно включить эту фичу в build.gradle
1 2 3 4 5 6 |
android { ... viewBinding { enabled = true } } |
Фича активируется после синхронизации gradle файлов.
Пусть у вас есть шаблон activity_main. Тогда фича создаст класс ActivityMainBinding, который предоставит доступ к View элементам — не нужно заниматься копированием id из макета, и выполнять monkey-job по вызову findViewById.
Пример кода для activity
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Инициализация binding binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) // Пример использования binding.textView.text = "Hello, View Binding!" binding.button.setOnClickListener { // Обработчик нажатия на кнопку } } } |
Обратите внимание, что setContentView также использует binding объект.
Пример кода использования binding во фрагменте
Здесь использована более сложная схема, т.к. у фрагментов более сложный жизненный цикл, чем у активити. Нам нужно чтобы binding функционировал пока существует view. И если вы обратитесь к binding за рамками onViewCreated — onDestroyView, то будет брошено исключение.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
class MyFragment : Fragment() { private var _binding: MyFragmentBinding? = null private val binding: MyFragmentBinding get() = _binding ?: throw RuntimeException("MyFragmentBinding is NULL") override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { // связываемся с шаблоном my_fragment.xml _binding = MyFragmentBinding.inflate(inflater, container, false) return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding.button.setOnClickListener { // Обработчик нажатия на кнопку } } override fun onDestroyView() { super.onDestroyView() _binding = null } } |