Мы продолжаем знакомство с технологиями, которые позволяют ускорить и упростить процесс разработки приложений под Android. В этой статье избавиться от шаблонного и необязательно кода нам поможет библиотека Data Binding.
Знакомство с Data Binding в Android
Вызов findViewById
для получения доступа к View является неоправдано громоздким особенно в больших проектах со сложными макетами и логикой работы. В таких случаях шаблонная часть, которая никак не относится к логике приложения, разрастается на десятки, а то и сотни строк.
Для упрощения процесса разработки и уменьшения количества строк кода были созданы сторонние библиотеки, например, ButterKnife — читайте обзор здесь. Она использует аннотации @BindView
, @BindString
, @BindDrawable
, @OnClick
и т.д. для замены шаблонного кода. Библиотека отлично справляется со своей задачей, но все также требует определения типов и указания идентификаторов для каждой view, пусть даже и в одну строку.
Интеграция Data Binding в проект Android Studio
Полностью избавиться от этого нам поможет Data Binding в Android. Давайте создадим новый проект в Android Studio и включим возможность использовать привязку данных в скрипте build.gradle
нашего проекта. Для этого добавьте следующую строку в блоке android
:
1 2 3 4 5 6 |
android { ... dataBinding { enabled true } } |
Теперь синхронизируем проект для завершения интеграции, как того хочет среда разработки Android Studio.
Теперь нам нужно внести необходимые изменения в макет activity_main.xml
. Сейчас он выглядит так:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.javadevblog.databindingapp.MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" /> </RelativeLayout> |
Мы должны поместить наш макет в корневой <layout>наш_макет</layout>
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <RelativeLayout xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.javadevblog.databindingapp.MainActivity"> <TextView android:id="@+id/tv_hello" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" /> </RelativeLayout> </layout> |
Обратите внимание, что мы также добавили обязательный атрибут id для TextView. Теперь перейдем в файл MainActivity.java
и внедрим data binding в коде:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
package com.javadevblog.databindingapp; import android.databinding.DataBindingUtil; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import com.javadevblog.databindingapp.databinding.ActivityMainBinding; public class MainActivity extends AppCompatActivity { ActivityMainBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this, R.layout.activity_main); } } |
В моем случае при попытке синхронизировать проект ActivityMainBinding не был создан, поэтому я просто пересобрал проект после добавления кода выше (пункт Build -> Rebuild Project).
Появляется вполне логичный вопрос: как появился класс ActivityMainBinding
, ведь мы его нигде не описывали? Здесь нет ничего магического: класс ActivityMainBinding.java
генерируется библиотекой Data Binding, когда среда разработки пересобирала приложение.
Почему именно ActivityMainBinding?
Имя класса происходит от имени файла макета (без расширения) activity_main.xml
с использованием верблюжьей нотации (CamelCase
— это ВерблюжийРегистр, стиль написания, в котором слова пишутся без пробелов с заглавной буквы) с добавлением с окончания «Binding». Таким образом у нас получилось следующее название класса для привязки данных:
activity_main.xml -> activity_main + Binding = ActivityMainBinding
Также обратите внимание на замену привычного метода setContentView()
на прокси-вызов библиотеки связывания: DataBindingUtil.setContentView()
. Он инициализирует генерированный класса с контекстом текущей активности.
Теперь попробуем получить доступ к нашей TextView внутри макета activity_main.xml
с помощью его идентификатора:
1 2 3 4 5 6 7 8 9 10 11 |
... public class MainActivity extends AppCompatActivity { ActivityMainBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this, R.layout.activity_main); binding.tvHello.setText("Привет Data Binding!"); } } |
Преобразование id в имя переменной
В приведенном выше примере каждый идентификатор @+id/
в файле XML автоматически преобразовывается в Java переменные. По сути, все сводится к простой замене подчеркиваний в CamelCase, однако есть несколько нюансов при такой трансформации:
Если бы у нас кроме tv_hello
также был идентификатор tvHello
, то библиотека связывания увидела бы только tv_hello
. Поэтому не используйте разные стили именования идентификаторов, иначе это может вызвать дополнительные сложности и проблемы при разработке.
Выводы
Библиотека Data Binding в Android обладает огромными возможностями ускорить и упростить процесс разработки, уменьшив при этом количество ненужного кода. Это позволяет сосредоточиться над созданием логики, а не поведением View в разных ситуациях.
На этом краткий обзор библиотеки связывания в Android подходит к концу. В следующих статьях мы поговорим о более продвинутых возможностях интеграции Data Binding в приложение на Android.
Подписывайтесь на новые материалы и делитесь этой статьей с друзьями!
Отлично, спасибо!