Обратное логическое значение с использованием двухсторонней привязки данных

Используя двустороннюю привязку данных Android, возможно ли иметь общий обратный логический преобразователь? Например, я хотел бы сделать что-то вроде этого:

<Switch android:checked="@={!viewModel.myBoolean}" />

Когда я запускаю это в Android, переключатель просто быстро срабатывает взад и вперед. Я попытался создать двустороннюю привязку app:inverseChecked, следуя некоторым примерам Джорджа Маунта, но мне это не удалось (просто продолжало появляться сообщение об ошибке невозможно найти событие 'inverseCheckedAttrChanged' в типе представления 'android.widget.Switch' ).

Для сравнения, используя Aurelia, это работает так, как и следовало ожидать для двусторонней привязки. В WPF, вероятно, первым конвертером, который вы делаете, является своего рода InverseBooleanConverter, который легко справляется с такими вещами. Итак, я предполагаю, что мне просто не хватает чего-то очевидного здесь.


person dukesta3    schedule 06.07.2016    source источник


Ответы (1)


Я вообще не ожидал, что это сработает. Я предполагаю, что он все время переключается туда и обратно, потому что привязки не применяют обратную функцию вашего выражения привязки.

Тем не менее, я протестировал поведение с текущей версией библиотеки привязки данных и проверил сгенерированные источники. На простом примере android:checked они показывают, как должно выглядеть обратное, и применяют его соответствующим образом.

Также Джордж Маунт недавно написал об этом сообщение в блоге: https://medium.com/google-developers/android-data-binding-inverse-functions-95aab4b11873

Если вы попытаетесь реализовать app:inverseChecked, вам также придется реализовать @BindingAdapter("inverseChecked") в качестве установщика, @InverseBindingAdapter(attribute="inverseChecked") в качестве геттера и @BindingAdapter("inverseCheckedAttrChanged") для настройки прослушивателя изменений.

Последний может выглядеть следующим образом:

@BindingAdapter("inverseCheckedAttrChanged")
public static void setupInverseCheckedAttrChanged(Switch view, InverseBindingListener listener) {
    OnCheckedChangeListener newListener = null;
    if (listener != null) {
        newListener = (v,b) -> listener.onChange();
    }
    view.setOnCheckedChangeListener(newListener);
}
person tynn    schedule 11.04.2017