В этом уроке знакомимся с Data Binding.

 


Полный список уроков курса:


 

 

В build.gradle файл модуля в секции android необходимо включить Data Binding:

android {
    ....
    dataBinding {
        enabled = true
    }
}

 

 

Правильно произносить байндинг, но биндинг звучит проще - буду использовать его.

Data Binding поможет организовать работу с View так, чтобы нам не пришлось писать кучу методов findViewById, setText, setOnClickListener и т.п. Давайте рассмотрим простой пример. 

 

Есть класс Employee, который содержит в себе данные о работнике

public class Employee {

   public Employee(long id, String name, String address) {
       this.id = id;
       this.name = name;
       this.address = address;
   }

   public long id;

   public String name;

   public String address;
}

поля: id, имя и адрес.

 

Мы хотим вывести имя и адрес работника на экран main_activity.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical">

   <TextView
       android:id="@+id/name"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"/>

   <TextView
       android:id="@+id/address"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"/>

</LinearLayout>

Несложная задача. Для этого мы обычно пишем методы findViewById и setText. Тут все понятно.

 

Давайте рассмотрим, как это же можно сделать с помощью Data Binding.

Вносим изменения в main_activity.xml:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

   <data>

       <variable
           name="employee"
           type="ru.startandroid.application.data.Employee" />

   </data>

<LinearLayout
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical">

       <TextView
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{employee.name}" />

       <TextView
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{employee.address}" />

   </LinearLayout>

</layout>

Корневым элементом теперь является <layout>, а LinearLayout сместился внутрь него.

В секции data мы объявляем переменную с именем employee. Ее тип - ранее рассмотренный класс Employee. Теперь мы можем использовать эту переменную в атрибутах вьюшек этого layout. В первом TextView, в атрибуте text мы используем employee.name, а в втором TextView - employee.address.

Обратите внимание, что мы не указываем id для View. В этом нет необходимости.

 

Как вы понимаете, нам остается лишь передать объект Employee в этот layout. И значения этого объекта будут подставлены в соответствующие TextView.

Это делается следующим образом.

public class MainActivity extends AppCompatActivity {

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);

       Employee employee = new Employee(1, "John Smith", "London");

       MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
       binding.setEmployee(employee);
   }
}

Сначала создаем Employee объект.

Затем используем DataBindingUtil. Метод DataBindingUtil.setContentView внутри себя сделает привычный нам setContentView для Activity, а также настроит и вернет объект биндинга MainActivityBinding.

MainActivityBinding - это сгенерированный класс. Имя этого класса берется из имени layout файла (т.е. main_activity), плюс слово Binding. MainActivityBinding все знает о нашем layout: какие View там есть, какие переменные (variable) мы там указывали, и как все это связать друг с другом, чтобы данные из переменных попадали в View.

Метод setEmployee был сгенерирован в классе биндинга, т.к. мы описали переменную employee в layout файле. Этим методом мы передаем биндингу объект Employee. Биндинг возьмет значения employee.name и employee.address и поместит их (методом setText) в соответствующие TextView. Все, как мы и настраивали в layout.

Запускаем приложение

Данные из Employee помещены в TextView.

 

Сразу хочу заметить, что если мы теперь в коде будем изменять объект Employee, то данные на экране меняться не будут. Они считались один раз и далее не отслеживаются (при такой реализации).

Чтобы экран получил новые данные, надо снова передать биндингу измененный объект Employee:

binding.setEmployee(employee);

 

Или можно вызывать метод invalidateAll:

binding.invalidateAll();

Биндинг считает новые данные с ранее полученного объекта Employee.  

 

 

Поля в Employee в этом примере я сделал public. Но вы можете сделать их private и создать для них public get методы.

 


Возможно, использование биндинга для пары TextView кажется бессмысленным. Но когда таких TextView десятки, то биндинг может избавить вас от написания кучи кода.

Кроме того, мы рассмотрели совсем простой случай использования биндинга. Но его возможности гораздо шире. Например, можно сделать так, чтобы при передаче в атрибут ImageView ссылки на картинку, биндинг запускал Picasso для загрузки этой картинки и помещал результат в ImageView. Или биндинг может сам отслеживать изменения в объекте с данными (в примере выше - это Employee ) и обновлять экран без каких-либо дополнительных методов.

Эти возможности мы рассмотрим в следующих уроках.


Присоединяйтесь к нам в Telegram:

- в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

- в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование 

- ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

- новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме 




Language

Социальные сети

 

Telegram канал



Android чат в Telegram



Группа ВКонтакте



Поддержка проекта

Яндекс
410011180491924

WebMoney
R248743991365
Z551306702056

Paypal