dukesta3
dukesta3

Reputation: 137

Inverse Boolean using Two Way Databinding

Using two-way Android Databinding, is it possible to have a generic inverse boolean converter? For example, I would like to do something like this:

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

When I run this in Android, the switch just rapidly fires back and forth. I tried to create a two way binding app:inverseChecked following some examples from George Mount, but I was not successful (just kept getting error stating cannot find event 'inverseCheckedAttrChanged' on View type 'android.widget.Switch').

As a comparison, using Aurelia this just works as you would expect for two way binding. In WPF, probably the first converter you make is some sort of InverseBooleanConverter to easily tackle these sorts of things. So, am assuming I am just missing something obvious here.

Upvotes: 1

Views: 1379

Answers (1)

tynn
tynn

Reputation: 39863

I actually didn't expect it to work at all. I assume, it's switching back and forth all the time, because the bindings don't apply inverse function of your binding expression.

That said, I tested the behavior with the current data binding library version and checked the generated sources. With the simple example of android:checked these show notes how the inverse should look like and apply it appropriately.

Also George Mount wrote a Blog post about it a short while ago: https://medium.com/google-developers/android-data-binding-inverse-functions-95aab4b11873

If you try to implement an app:inverseChecked, you'd also have to implement a @BindingAdapter("inverseChecked") as setter, @InverseBindingAdapter(attribute="inverseChecked") as getter and @BindingAdapter("inverseCheckedAttrChanged") for setting up the change listener.

The latter could look like the following:

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

Upvotes: 1

Related Questions