#android #android-databinding
#Android #android-привязка данных
Вопрос:
Я новичок в разработке Android и экспериментирую с двусторонней привязкой данных. Хотя я смог выполнить некоторые базовые привязки между представлением и моделью, я столкнулся со сценарием, в котором мне нужно обновить отношение «многие ко многим» между двумя объектами.
Рассмотрим следующий (надуманный) пример:
public class Person extends BaseObservable {
private Set<Thing> things;
@Bindable
public boolean hasThing(Thing thing) {
return things.contains(thing);
}
public void setHasThing(Thing thing, boolean hasThing) {
boolean changed = hasThing
? things.add(thing)
: things.remove(thing);
if (changed) {
// notify change
}
}
}
Я хотел бы связать onChecked
событие с действием добавления или удаления a Thing
из a Person
:
<data>
<variable name="person" type="org.example.model.Person"/>
<variable name="thing" type="org.example.model.Thing"/>
</data>
<!-- obviously doesn't work -->
<androidx.appcompat.widget.SwitchCompat
android:checked="@={person.hasThing(thing)}"/>
Каков наилучший способ добиться этого? Я изучил @BindingMethod
и @BindingAdapter
, но:
- Согласно Javadoc,
@BindingMethod
имеет ограничения на параметры и возвращаемые типы методов, которые, по-видимому, делают его более подходящим для таких случаев использования, как преобразования типов @BindingAdapter
/@InverseBindingAdapter
кажется многообещающим, но я изо всех сил пытаюсь понять, как запустить адаптер:<androidx.appcompat.widget.SwitchCompat android:checked="@={?}" app:person="@{person}" app:thing="@{thing}"/>
Заранее спасибо!
Ответ №1:
Оказывается, я делал это сложнее, чем нужно.
Работает следующее:
<data>
<variable name="person" type="org.example.model.Person"/>
<variable name="thing" type="org.example.model.Thing"/>
</data>
<androidx.appcompat.widget.SwitchCompat
android:checked="@{person.hasThing(thing)}"
app:onCheckedChanged="@{(view, checked) -> person.setHasThing(thing, checked)}"/>
@BindingAdapter("onCheckedChanged")
public static void setOnCheckedChangeListener(CompoundButton button, CompoundButton.OnCheckedChangeListener changeListener) {
button.setOnCheckedChangeListener(changeListener);
}