androiddata-bindingkotlinandroid-binding-adapter

BindingAdapter doesn't work with DataBinding


I've got a button:

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:binding="http://schemas.android.com/tools">

    <data>

        <variable
            name="vm"
            type="com.MyViewModel" />
    </data>
    <Button
                binding:singleParameterString="test"
                binding:firstStringParameter="@{vm.userName}"
    .../>
...

The BindingAdapter looks as follows:

@BindingAdapter("binding:singleParameterString", "binding:firstStringParameter")
        fun setFormattedString(btn: Button, singleParameterString: String, firstStringParameter: String) {
            btn.text = String.format(singleParameterString, firstStringParameter)
        }

This doesn't work, it gives the following error: "Cannot find the setter for attribute 'binding:firstStringParameter' with parameter type java.lang.String on android.widget.Button.". However, if I change binding:firstStringParameter="@{vm.userName}" to, for example, binding:firstStringParameter="my lovely string" this will work.

The userName in the ViewModel is val userName: String = "my name" and if I try android:text="@{vm.userName}" that works. So the problem is in the databinding. I've got another project where I used the same code and it works... Sounds like a bug in the databinding/adaperbinding framework, but maybe someone came across this problem?

P.S. I also tried binding:firstStringParameter="@{ + vm.userName}", did not work.

By looking at the autogenerated Binding class I discovered a very strange code:

blah.setFormattedString(this.mboundView1, (java.lang.String)null, javaLangStringVmUserName);

Solution

  • Ok, the library is broken. I found a solution. It will only work if both parameters are either hardcoded strings OR are passed from the ViewModel.

    So, that

    binding:firstStringParameter="@{vm.
    binding:singleParameterString="@{vm.test}"
    

    and that works:

     binding:firstStringParameter="userName"
     binding:singleParameterString="test"
    

    , but this doesn't work:

     binding:firstStringParameter="@{vm.userName}"
     binding:singleParameterString="test"