Привязка данных Android: BindingAdapter и InverseBindingAdapter

Какая разница между двумя?

Когда следует использовать тот или иной?

Когда я определяю BindingAdapter, нужно ли мне создавать инверсию?


person Veneet Reddy    schedule 12.08.2017    source источник


Ответы (1)


Цитирую себя из Руководства занятого кодера по разработке для Android:

Двусторонняя привязка хорошо работает в тех случаях, когда способ хранения данных в моделях хорошо согласуется с геттерами и сеттерами связанного виджета. Поле boolean в модели хорошо работает с проверенным свойством CompoundButton, как и Switch, поскольку CompoundButton имеет метод isChecked(), возвращающий boolean, и setChecked(), принимающий boolean.

BindingAdapter позволяет создавать другие сопоставления между типами данных и свойствами, но только для классической привязки модель->представление. Чтобы выполнить то же самое в обратном направлении, вы создаете файл InverseBindingAdapter. Как следует из названия, он выполняет ту же основную роль, что и BindingAdapter, но в обратном направлении, беря данные из виджета и подготавливая их для модели с помощью пользовательского кода. Здесь «подготовка его для модели» означает преобразование его в подходящий тип данных для сеттера, поля Observable и т. д. для вашей модели.

Это довольно необычно.

В некоторых местах используется пример: «Что, если я хочу связать float с EditText?». InverseBindingAdapter будет выглядеть примерно так:

@InverseBindingAdapter(attribute = "android:text")
public static float getFloat(EditText et) {
  try {
    return(Float.parseFloat(et.getText().toString()));
  }
  catch (NumberFormatException e) {
    return(0.0f); // because, um, what else can we do?
  }
}

Проблема заключается в том, что пользователь вводит что-то, что не является допустимым числом с плавающей запятой, например snicklefritz. parseFloat() потерпит неудачу с NumberFormatException. Вы должны сообщить пользователю, что введенные им данные недействительны. Однако двусторонняя привязка данных не поддерживает это, вместо этого модели передается значение по умолчанию (например, 0.0f).

Итак, отвечая на ваши вопросы:

Какая разница между двумя?

BindingAdapter помогает заполнять свойства, где типы данных и View сеттеры не являются чем-то, что привязка данных знает, как обрабатывать самостоятельно.

InverseBindingAdapter помогает заполнять модели представлений при двусторонней привязке, где типы данных и геттеры View не являются чем-то, что привязка данных умеет обрабатывать самостоятельно.

Когда следует использовать тот или иной? Когда я определяю BindingAdapter, нужно ли мне создавать инверсию?

Используйте BindingAdapter, когда желаемый тип данных (например, float) не является чем-то, что связывание данных обязательно знает, как заполнить свойство виджета (например, android:text для EditText), но вы все равно хотите его связать.

Если вы сделаете это, и вы хотите выполнить двустороннюю привязку, при которой пользовательские изменения в пользовательском интерфейсе автоматически обновляют вашу модель представления, скорее всего, вам потребуется соответствующий InverseBindingAdapter для преобразования из свойства (например, , текст EditText) в желаемый тип данных (например, float).

person CommonsWare    schedule 12.08.2017