Какая разница между двумя?
Когда следует использовать тот или иной?
Когда я определяю BindingAdapter
, нужно ли мне создавать инверсию?
Какая разница между двумя?
Когда следует использовать тот или иной?
Когда я определяю BindingAdapter
, нужно ли мне создавать инверсию?
Цитирую себя из Руководства занятого кодера по разработке для 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
).