Parsing Data Binding Errors

08 Dec 2017 | Comments

Learning something new is always fun and exciting. That is, until seemingly cryptic error messages start creeping up.

For the past year, I have been helping my teammates get more acquainted with data binding. One topic that frequently comes up is that if something goes wrong, it can be hard to figure out exactly why.

I have talked a lot about data binding, and the past couple of times that I did, I decided to include a section on a few of the errors I see most often.

1

This error means the layout file is using a variable (“user defined types”) called library, but it is has not been declared within the data element.

To fix this, make sure that any variables being used in the layout file have been declared. If they are, double check that there are no typos as well!

<data>
    <variable
        name="library"
        type="io.plaidapp.ui.AboutActivity.Library" />
</data>
<io.plaidapp.ui.widget.BaselineGridTextView
   android:id="@+id/library_description"
   android:text="@{library.description}" />

It turns out that I have reported this in the issue tracker, hopefully the team gets around to it soon! :smile:

2

If I remember correctly, during the early days of data binding, the BindingAdapter implementations would have the namespace included in the annotations. It did seem to ignore it, and at some point in the past year, this warning popped up.

It is not an error, but if you want to fix the warning, remove the namespace declaration and everything should be good to go!

@BindingAdapter({"imageUrl", "circleCrop"})
public static void setAvatar(ImageView imageView, String url, boolean isCircleCropped) {
   // Do stuff
}

3

Observable fields may be one of my most favourite things in data binding. If you are not familiar, I highly suggest reading up on them and trying them out.

To fix this warning, check that any Observable being used in a BindingAdapter uses the values (“contents”) directly.

As an example, say I have an ObservableBoolean called shouldLoadUserAvatar that I use in a layout file like this:

app:shouldLoadUserAvatar="@{dribbbleState.shouldLoadUserAvatar}"

In the BindingAdapter implementation, you can (and should) use a Boolean to get the value that we want:

@BindingAdapter({"userAvatar", "shouldLoadUserAvatar"})
public static void setPlayerCommentAvatar(ImageView imageView, String userAvatar, Boolean shouldLoadUserAvatar) {
   if (shouldLoadUserAvatar) {
       // Do stuff
   }
}

If there are more errors you see whilst using data binding, please share them (and how to fix them, if you can!) in the comments below!