[Из песочницы] Быстрый старт Data Binding в Android

Введение Профессионально андроид-разработкой занимаюсь чуть больше года, до этого разрабатывал по Windows Phone и мне понравилась возможность связывать данные из вью модели с самим View при помощи механизма Bindings. А после изучения RX, многие задачи стали решаться более чисто, вью-модель полностью отделилась от View. Она стала оперировать только моделью, совсем не заботясь о том, как она будет отображаться.В Android такой строгости я не заметил, Activity или Fragment как простейшие представители контроллера чаще всего имеют полный доступ как ко View, так и к модели, зачастуя решая, какой View будет видим, решая таким образом чисто вьюшные задачи. Поэтому я довольно радостно воспринял новость о появлении Data Binding в Android на прошедшем Google IO.

[embedded content]

Пока что это только бета релиз, но уже можно протестировать функционал и увидеть направление, в котором двигаются разработчики из Google.

Начало Я использую Android Studio 1.3.Для сборки используется новый android плагин для Gradle (нужна версия 1.3.0-beta1 и старше). Так как связи отрабатываются во время компиляции, нам понадобиться ещё один плагин к Gradle 'com.android.databinding: dataBinder:1.0-rc0'. В отличие от того же Windows Phone где механизм привязок реализован глубоко по средством DependencyProperty и в RealTime, в Android эта функция реализуется как бы поверх обычных свойств, во время компиляции и дополнительной кодогенерации, поэтому в случае ошибок будьте готовы разбирать ответ от компилятора.

Итак, заходим в файл build.gradle, который лежит в корневом каталоге проекта (в нём идут настройки Gradle для всего проекта). В блоке dependencies вставляем:

dependencies { classpath 'com.android.tools.build: gradle:1.3.0-beta2' classpath 'com.android.databinding: dataBinder:1.0-rc0' } Теперь подключим плагин к конкретному модулю, откроем build.gradle файл, который лежит внутри модуля. По умолчанию app/build.gradle и добавим строчку: apply plugin: 'com.android.databinding' Настройка Layout Мы должны обернуть наш внешний View в тег . Cтудия сейчас подчеркивает его красным и требует ему назначить атрибуты высоты и ширины; игнорируем её, иначе получим ошибку дубликации атрибутов. Этим действием вы сказали плагину биндинга генерировать класс связывания. По умолчанию имя этого класс будет выбираться на основе названия файла разметки. Для main_activity — MainActivityBinding, который будет доступен для импорта из пакета, для меня com.georgeci.bindingssample.databinding.ActivityMainBindingВажно: если в разметке не будет View с Id или тега класс биндинг не создастся.

Уже сейчас можно начать его использовать класс Binding для доступа к элементам интерфейса, без использования findViewById. В MainActivity добавим поле и перепишем метод onCreate: ActivityMainBinding binder;

@Override protected void onCreate (Bundle savedInstanceState) { super.onCreate (savedInstanceState); binding = DataBindingUtil.setContentView (this, R.layout.activity_main); binding.bindTv.setText («Some text»); } Название поля берётся из Id View, без Id в биндере поле не появиться, если изменить Id View, то поле в биндере сразу же переметнуться. Если с зажатым CTRL нажать на название поля View, то сразу перейдешь к нему в файле разметки. Как по мне так уже одного такого функционала достаточно для того чтобы начать использовать биндинги.Мои предвкушения Но это лишь начало и идёт как бонус, главная особенность это конечно же использование самого Layout файла для разметки того какие данные куда размещать и как следствие возможность реализации паттерна MVVM как это происходит в С# в Windows приложениях. А если ещё и приложить мощь Java RX, но не будем отвлекаться.

Привязка данных Например у нас есть карточка пользователя имя и возраст. public class User { public String name; public int age;

public User (String name, int age) { this.nam = name; this.age = age; } } Изменим Layout, заменим содержимое LinearLayout на:

И в onCreate заменим последнюю строку на: binding.setUser (new User («Some name», 27)); Запускаем. Всё работает.Наверное у всех проектах в активити или в фрагментах встречается такие строчки: someView.setVisibility (isVisible: View.VISIBLE: View.GONE); Тут то мы и начинаем использовать непосредственно привязки данных. Перепишем модель: public class User { public String name; public int age;

public User (String name, int age, boolean isAdult) { this.name = name; this.age = age; this.isAdult = isAdult; } public boolean isAdult; } И добавим в Layout: На красные выделения студии игнорируем.Так как мы используем класс View, то его нужно импортировать, добавим в ноду : Или используем его вместе с названием пакета: android: visibility=»@{user.isAdult? android.view.View.VISIBLE: android.view.View.GONE}» Так же возможно в ноде задать псевдоним для класса: … android: visibility=»@{user.isAdult? SomeAlias.VISIBLE: SomeAlias.GONE}» Конвертеры Импорт в свою очередь даёт возможность писать конвертеры. Добавим в модель поле с датой рождения и удалим возраст: public class User { public String name; public long birthday; public boolean isAdult; public User (String name, long birthday, boolean isAdult) { this.name = name; this.birthday = birthday; this.isAdult = isAdult; } } Напишем конвертер: public class UnixDateConverter { public static String convert (long timestamp) { Calendar mydate = Calendar.getInstance (); mydate.setTimeInMillis (timestamp * 1000); SimpleDateFormat sdf = new SimpleDateFormat («MM/dd/yyyy»); return sdf.format (mydate.getTime ()); } }

Импортируем его в разметку:

Обратная связь и Binding Попробуем сменить имя пользователя.Добавим в Layout: