Android Data Binding

Android provides data binding library that helps in creating apps with less glue code to bind application logic and layouts. With data binding, you don’t need to find views in activities or fragments, set view attributes to properties of data model object and add event handlers to views, all this is taken care of by data binding framework using the data binding component classes and data binding expressions that you define in layouts.

Data binding compiler tool generates necessary code to make the binding work using xml layout and data binding component classes defined using annotations.

Project Setup

The Data Binding Library offers both flexibility and broad compatibility – it’s a support library, so you can use it with all Android platform versions back to Android 2.1 (API level 7+). To use data binding, you need to enable it by adding below configuration to modulebuild.gradle file.

1

2

3

4

5

6

android{

....

dataBinding{

enabled=true

}

}

If you have an app module that depends on a library which uses data binding, your app module must configure data binding in its build.gradle file as well.

Data Binding

To use data binding framework, first you need to create data model object, then define your activity layout with data binding elements and expressions. Lets create a simple User Model.

1

2

3

4

5

6

7

8

publicclassUser{

publicfinalStringfirstName;

publicfinalStringlastName;

publicUser(StringfirstName,StringlastName){

this.firstName=firstName;

this.lastName=lastName;

}

}

Notice in the below example that layout’s root element is layout and data model object variable is declared using variable element under data element.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<?xml version="1.0"encoding="utf-8"?>

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

<data>

<variable name="user"type="com.example.User"/>

</data>

<LinearLayout

android:orientation="vertical"

android:layout_width="match_parent"

android:layout_height="match_parent">

<TextView android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="@{user.firstName}"/>

<TextView android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="@{user.lastName}"/>

</LinearLayout>

</layout>

The user variable within data describes a property that may be used within this layout.

1

<variable name="user"type="com.example.User"/>

Expressions within the layout are written in the attribute properties using the “@{}” syntax. Here, the TextView’s text is set to the firstName property of user:

1

2

3

<TextView android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="@{user.firstName}"/>

By default, a Binding class will be generated based on the name of the layout file, converting it to Pascal case and suffixing “Binding” to it. The above layout file was main_activity.xml so the generated class was MainActivityBinding. This class holds all the bindings from the layout properties (e.g. the user variable) to the layout’s Views and knows how to assign values for the binding expressions.The easiest means for creating the bindings is to do it while inflating:

If you run the above example, it will display data object value in UI widget. But using @{} expression as shown above will just bind the value of the property of data object to the attribute of View. But it won’t refresh the UI widget with the changed value of the property of the object and it won’t populate the data object with user entered or modified value into the UI widget.

Data binding does not support include as a direct child of a merge element. For example, the following layout is not supported:

1

2

3

4

5

6

7

8

9

10

11

12

13

<?xml version="1.0"encoding="utf-8"?>

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

xmlns:bind="http://schemas.android.com/apk/res-auto">

<data>

<variable name="user"type="com.example.User"/>

</data>

<merge>

<include layout="@layout/name"

bind:user="@{user}"/>

<include layout="@layout/contact"

bind:user="@{user}"/>

</merge>

</layout>

Includes

Variables may be passed into an included layout’s binding from the containing layout by using the application namespace and the variable name in an attribute:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

<?xml version="1.0"encoding="utf-8"?>

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

xmlns:bind="http://schemas.android.com/apk/res-auto">

<data>

<variable name="user"type="com.example.User"/>

</data>

<LinearLayout

android:orientation="vertical"

android:layout_width="match_parent"

android:layout_height="match_parent">

<include layout="@layout/name"

bind:user="@{user}"/>

<include layout="@layout/contact"

bind:user="@{user}"/>

</LinearLayout>

</layout>

Here, there must be a user variable in both the name.xml and contact.xml layout files.

Conclusion

Data Binding is a powerful tool to reduce boilerplate code, when binding or referencing views that show data. In heavy UI intensive application like Calculator, you will find yourself repeating almost the line of code over and over again. Data binding also offers Two Way Data Binding, which I will cover later. Remember to share and leave comments 🙂

Post navigation

About Me

Hello I am Juma Allan, Founder and Author of Android Study. I am currently working as the Lead Android Engineer at dLight Solar, an Open Source Enthusiast and a big time Android Lover, learning Go and sharing my knowledge with others.

“If you don’t build your dream someone will hire you to help build theirs”