Android applications are, almost universally, data driven. All screens have a data object that can be fetched from the internet, database, or even created by the application user. Typically on Android apps, developers need to inflate the view, locate each view element using findById, and then set the appropriate value. To make this process faster and more effective, Google released the Data Binding Support Library, which provides a cleaner way to tie upthe code logic to the view layer, thereby minimizing the necessary work to reference each view element.

How it Works

The Data Binding API uses the Java Annotation Processor to generate the java classes on compile time. It's a kind of java compile plugin that inspects the code, looking for particular annotations to generate or modify the code.

The only two requirements to use data binding are:

  1. Android plugin for Gradle 1.5.0-alpha1 and
  2. DataBinding enabled on your build.gradle file:

android { 

    ....

    dataBinding {

        enabled = true

    }

}

All layouts should have the tag <layout>:

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

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

    xmlns:tools="http://schemas.android.com/tools">

 

    ....

 

</layout> 

When the project is compiling, the plugin will look for layout files with this tag and generate an equivalent java version. This class will have the same name as the xml file, converting it to Pascal case and "Binding" suffix, so if the layout's name is activity_main.xml, the java class will be ActivityMainBinding.java.

The layout inflate will be a little bit different, using the DataBindingUtils.java helper:

Inside activities:

@Override

protected void onCreate(Bundle savedInstanceState) { 

    super.onCreate(savedInstanceState);

    ActivityMainBinding binding =  DataBindingUtil.setContentView(this, R.layout.activity_main);

}

Inside fragments:

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { 

    ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);

    return binding.getRoot();

}

Good Bye ButterKnife

One of the best features provided by data binding is the layout binding. It is similar to ButterKnife, but you don't need to create an instance of each view with the respective annotations. The entire process is automatic, and the plugin will generate a class with all elements. The only requirement is to define a view id.

activity_main.xml

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

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

    xmlns:tools="http://schemas.android.com/tools">

 

    <RelativeLayout

        android:id="@+id/activity_main"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:paddingBottom="@dimen/activity_vertical_margin"

        android:paddingLeft="@dimen/activity_horizontal_margin"

        android:paddingRight="@dimen/activity_horizontal_margin"

        android:paddingTop="@dimen/activity_vertical_margin"

        tools:context="com.binding.data.avenuecode.databindingexample.MainActivity">

 

        <TextView

            android:id="@+id/hello_world_text_view"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="Hello World!" />

    </RelativeLayout>

</layout> 

The API generates the view instance inside the ActivityMainBinding.java:

public final android.widget.RelativeLayout activityMain; 

public final android.widget.TextView helloWorldTextView;

A parameter will be created for each element with defined id, generating the name based on id and converting it to Pascal case. That way, it is possible to access all views and make all necessary changes, much faster and easier than findViewById or ButterKnife.

Binding Objects

Another important feature implemented by the API is binding objects. Now it is possible to use instances of objects directly on the layout. First, insert the tag <data></data> above the root ViewGroup, then add the tag <variable>:

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

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

    xmlns:tools="http://schemas.android.com/tools">

 

    <data>

        <variable

            name="mainActivity"

            type="com.binding.data.avenuecode.databindingexample.MainActivity"/>

    </data>

 

    <RelativeLayout

        android:id="@+id/activity_main"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:paddingBottom="@dimen/activity_vertical_margin"

        android:paddingLeft="@dimen/activity_horizontal_margin"

        android:paddingRight="@dimen/activity_horizontal_margin"

        android:paddingTop="@dimen/activity_vertical_margin"

        tools:context="com.binding.data.avenuecode.databindingexample.MainActivity">

 

        <TextView

            android:id="@+id/hello_world_text_view"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="Hello World!" />

    </RelativeLayout>

</layout> 

The expressions to access these object properties need to be written inside the attribute @{}:

...

<TextView 

    android:id="@+id/hello_world_text_view"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:text="@{mainActivity.helloText}" />

...

The property can be accessed publicly or through getters:

...

public String getHelloText() { 

    return "Hello World!";

}

...

The Takeaway

DataBinding is a powerful API that enables development with less code, in a faster and more organized way. One disadvantage is that because the documentation is subpar, and due to be uploaded to a new library, it is sometimes difficult to find help for advanced uses. I will introduce some advanced features in future articles, and explain the advantages of using MVVM with DataBinding.


Author

Marcus Vinicius Corrêa Barcelos

Marcus Vinicius Corrêa Barcelos is an Android Engineer at Avenue Code.


Building Accessible Web Applications

READ MORE

Create a Tunnel from Anypoint Platform to GCP Using an HA VPN

READ MORE

Create a Classic Tunnel from GCP to Anypoint Platform

READ MORE

How to Make an Android Splash Screen

READ MORE