Android data binding

Every Android developer knows the usual tiresome way of binding their application logic with layouts. Tens or even hundreds of boilerplate code lines containing the findViewById methods and never-ending manual updating of view properties based on changes in data. Thankfully, Android data binding support library comes to help automate things and simplify your code.

Android data binding support library

Android data binding support library has been released along with Android Marshmallow. Being a support library, data binding is therefore available in all Android versions back to SDK v7.

To enable data binding in your project, Gradle 1.5.0 and higher is required and the following lines present in the module level build.gradle file of your project:

After a project sync, you can make full use of the data binding in Android.

Let’s see what you can achieve with it in a simple example project showing a list of articles, each containing a featured image, article title, excerpt, a button with the number of comments and a button navigating to a hypothetical detail of the article. The application looks like this on a device:

To make our example application complete, let me first present the content of the holding activity class and its layout file. The activity does nothing but holds a single RecyclerView displaying the content of list of Article data objects using a custom adapter. Data binding is used here as well so don’t worry about not understanding every line of code. They will be explained in short.

All we need to do now is to create a layout XML file representing the article item, an  Article data model class and an adapter for the RecyclerView. We shall look into these in more detail in the following sections.

Data model objects

Any plain old Java object (POJO) can be used as a data supply for data binding in Android. However, by doing only this, you would lose one of the main advantages data binding usage has and that’s automatic view updates upon object properties change.

In our example, this is how the Article data object could look like:

In order to make use of automatic view updates, there are three options you could go with. You could either create an observable object, observable fields, or observable collections.

The easiest way to go for a developer is to use a data class implementing the Observable interface. Android provides a convenience class BaseObservable which your data classes can extend and which takes care of listener registration. The developer is, however, still responsible for notifying of property changes. This is done by assigning the @Bindable annotation to the property getter and notifying in the property setter.

This is the Article class updated to extend the BaseObservable class:

The getter for the title of the article getTitle has been annotated by the @Bindable annotation and notifyPropertyChanged(BR.title) has been added in the setter setTitle. When an article is read, setRead(true) method is called and it adds the “READ” word to the beginning of the original title.

To complete the data class code, a few more lines have to be added. Namely, two OnClickListeners for buttons.

With the data class prepared, let’s head to the most important part of Android data binding — the layout XML file.

Structure of layout files

The structure of Android data binding layout files is very similar to the regular layout XML files. The data binding XML file in addition contains the layout root element followed by the data element and the view root element. The view root element then contains the usual view declarations.

The data section contains variable elements describing properties to be used within your layouts.

Layout expressions are written in the attribute properties using the @{} syntax. Here is an example of setting the text of TextView to the title property of the Article model object.

A full layout XML file of article list item follows:

Let’s go from the top of the layout XML file down and describe each usage of Android data binding expression.

First, in the data section, we define two variables: article which is of type  com.example.databindingblog.Article and refers to our previously described Article data class; and view of type android.view.View which refers to the Android View class. The latter is used later for accessing the view’s visibility constants in Android data binding expressions.

The first real usage of Android data binding is present in the CardView’s app:cardBackgroundColor attribute. Using a ternary operator, it is decided whether the article is supposed to be highlighted. Based on the value, we set the colour of the card background. As you can see, the colour can either be represented as a hexadecimal value or defined in Android resources.

Next follows an ImageView with app:image attribute. This Android data binding usage expression uses a custom setter which shall be explained in Advanced binding section down below.

The two TextView XML definitions below simply use the property values from Article data object to show a text (article title and excerpt).

Next, there are two buttons, a button referring to a hypothetical article detail labeled “Read more” and a button showing the number of comments and allowing to click-through to see them.

In the XML layout file, we can also define onClick attributes referring to specific implementations in the Article class.

Android data binding expression language also allows developers to easily use plural string definitions. We use this feature in our comments button which changes its label depending on the count of comments. The android:text attribute then looks like this:

And the numberOfComments plural string is defined in the Android resources as follows:

In case no comments are associated with the article, the comments button is hidden. This is where it comes to the use of the  view variable and its constants for view visibility.

One of the nice features worth mentioning is the null coalescing operator ??. If the value of expression before the operator is null, then the following expression value is used. An example follows:

The Android data binding library also makes automatically sure to check for nullity of variables and provides defaults ( null for String, 0 for int, etc.) if needed.

For a comprehensive list of Android data binding expression language features, please see the official documentation.

Binding the parts together

There are several ways of creating the binding connection. However, the official documentation recommends to create the binding soon after layout inflation. One way is to use the generated Binding class (the full name depends on your layout XML filename — converted to CamelCase and with Binding appended):

In our example, we use a second approach of binding inside of an adapter using DataBindingUtil’s static methods:

Advanced binding

In this section, custom setters and converters will be introduced. These features allow the developer to customize the Android data binding mechanisms to better suit their needs.

Custom setters

You might soon run into the need of custom attributes logic. That’s what BindingAdapters are good for. By using them, the developer can either create new view attributes or override their default behaviour.

One of the most common examples is loading images off the main thread:

In the Article data model class, the BindingAdapter method is defined as follows (we use Glide image loading library here):

Converters

Custom converters can be supplied to transform one type of attribute to another. For example when the attribute expects a Drawable and you want to supply a colour from Android resources. Custom converter could then convert the integer value of colour to ColorDrawable:

Conclusion

The presented Android data binding possibilities are only a subset of what the library has to provide. However, I hope I was able to mention some of the most common use cases and explained how the Android data binding library works in general. In the next post, I’ll stick to the subject of Android data binding and introduce the MVVM (Model-View-ViewModel) architecture pattern which has been designed to better separate your code and make it testable more easily.

Unfortunately, currently, Android data binding library cannot be used together with the Jack compiler toolchain. That means that for the meantime, you have to chose between data binding and using Java 8 language features, such as lambda expressions or Stream API, both of which I’ve introduced in previous posts.

Here, you can download the whole example application project.

Sources

Share this:

5 thoughts on “Android data binding

  1. Nice Article Sir.
    I have a question, can I use that data binding on java7 ? or I must upgrade into java8 ?
    because I got error, “cannot resolve symbol BR”,
    Can you help me?
    Sorry for my bad english.

    • Hello zigicgunz, in fact, you cannot use data binding with Java 8 just yet. So staying with Java 7 is OK. It seems that the problem you’re facing is that you haven’t built your project. That’s why your data binding classes weren’t generated.

  2. Hey Milan!
    Great article! I have studied this one and the MVVM (Model-View-ViewModel) architecture pattern and I love how simple and concise you walk us towards understanding how data binding can be implemented. However, in both articles, your download link to the project doesn’t. I’d love to review and run your app so as to learn the ins and outs of if.

    Apart from that keep up the awesome work and looking forward to more content from you!

Leave a Comment