Использование привязки данных Android со связью «многие ко многим» в модели

#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);
}