× Home Tutorials Training Consulting Products Books Company Donate Contact us









NOW Hiring

Quick links

Share

This tutorial describes the usage of data binding in Android applications to synchronize your user interface with your application model and logic..

1. Android data binding

1.1. Introduction to data binding in Android

Android offers support to write declarative layouts using data binding. This minimizes the necessary code in your application logic to connect to the user interface elements.

db android10

To use data binding, Android Plugin for Gradle 1.5.0 or higher is required.

To enable the usage of data binding in your Android application, add the following snippet to the app/build.gradle file.

android {
    ....
    dataBinding {
        enabled = true
    }
}

The data binding information is added to your layout files. During the build process this information is and Binding classes are generated based on its information. By default, the name of the Binding class is generated based on the name of the layout file. It converts the name to Pascal case and adds the “Binding” suffix to it. For example, if the layout file is called activity_main.xml, the generate class is called ActivityMainBinding. This class holds all the bindings from the layout properties, i.e., the defined variable to the corresponding views. It also knows how to assign values for the binding expressions.

Layout files which supports data binding start with a layout root tag followed by a data element and a view root element. This view element is what your root would be in a non-binding layout file. The data elements describe data which is available for binding, expressions within the layout are written in the attribute properties using the “@{}” syntax.

A sample file looks like the following listing.

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
   <data>
       <variable name="user" type="com.vogella.android.databinding.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.2. Data binding for events

Events may be bound to handler methods directly, similar to the way android:onClick can be assigned to a method in the activity. Event attribute names are governed by the name of the listener method with a few exceptions. For example, View.OnLongClickListener has a method onLongClick(), so the attribute for this event is android:onLongClick.

To assign an event to its handler, use a normal binding expression, with the value being the method name to call. The binding expression can assign the click listener for a View.

1.3. Updating the user interfaces with changes from the data model

Any plain old Java object (POJO) can be used for data binding, but modifying such a Java object will not cause the UI to update. To enable this, the data objects must be able to notify about data changes. There are three different data change notification mechanisms, Observable objects, observable fields, and observable collections.

Android provides the BaseObservable class which you can extend. The data class is responsible for notifying when the properties change. This is done by assigning a @Bindable annotation to the getter and notifying in the setter.

package com.vogella.android.databinding;


import android.databinding.BaseObservable;
import android.databinding.Bindable;

import java.util.Observable;

public class TemperatureData extends BaseObservable {
    private String celsius;

    public TemperatureData(String celsius) {
        this.celsius = celsius;
    }

    @Bindable                                      (1)
    public String getCelsius() {
        return celsius;
    }

    public void setCelsius(String celsius) {
        this.celsius = celsius;
        notifyPropertyChanged(BR.celsius);         (2)
    }
}
1 Define a relevant getter
2 Notify any listeners, BR.celsius is a generated class

This listener is invoked on every update and it updates the corresponding views. This ensures that updates in the model updates also the UI.

1.4. Example for using data binding

Layout files which supports data binding start with a layout root tag followed by a data element and a view root element. This view element is what your root would be in a non-binding layout file. The data elements describe data which is available for binding, expressions within the layout are written in the attribute properties using the “@{}” syntax.

A sample file looks like the following listing.

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
   <data>
       <variable name="user" type="com.vogella.android.databinding.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.

The data object used with this layout may look like the following listing.

package com.vogella.android.databinding;

public class User {
   public final String firstName;
   public final String lastName;

   public User(String firstName, String lastName) {
       this.firstName = firstName;
       this.lastName = lastName;
   }
}
package com.vogella.android.databinding;

import android.app.Activity;
import android.databinding.DataBindingUtil;
import android.databinding.ViewDataBinding;
import android.os.Bundle;

import com.vogella.android.databinding.databinding.ActivityMainBinding;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        User user = new User("Test", "User");
        binding.setUser(user);
    }
}

2. Exercise: Use data binding

In this exercise you learn how to interact between your user interface widgets using data binding. Create a new Android application for this exercise, with the com.vogella.android.databinding top level package.

2.1. Activate the usage of data binding

Open your app/build.gradle file and activate the usage of databinding. Ensure you pick the correct build file, it is the one with the application node in it.

apply plugin: 'com.android.application'

android {

    dataBinding {
        enabled = true
    }

        .... [REST AS BEFORE...]

2.2. Create classes for the view interaction

Create the following classes.

package com.vogella.android.databinding;


import android.databinding.BaseObservable;
import android.databinding.Bindable;
import android.databinding.ObservableField;

import java.util.Observable;

public class TemperatureData extends BaseObservable{
    private String celsius;

    public TemperatureData(String celsius) {
        this.celsius = celsius;
    }

    private String fahrenheit;

    @Bindable
    public String getCelsius() {
        return celsius;
    }


    public void setCelsius(String celsius) {

        this.celsius = celsius;
        notifyPropertyChanged(BR.celsius);
    }


}
package com.vogella.android.databinding;


public interface MainActivityContract {
    public interface Presenter {
        void onShowData(TemperatureData temperatureData);
    }

    public interface View {
        void showData(TemperatureData temperatureData);
    }

}
package com.vogella.android.databinding;

import android.util.Log;
import android.view.View;
import android.widget.Toast;


public class MainActivityPresenter {
    private MainActivityContract.View view;

    public MainActivityPresenter(MainActivityContract.View view) {

        this.view = view;
    }
    public void onShowData(TemperatureData temperatureData) {
        view.showData(temperatureData);
    }
}

2.3. Adjust layout files to use data binding

Change the layout to the following.

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable
            name="temp"
            type="com.vogella.android.databinding.TemperatureData" />
        <variable
            name="presenter"
            type="com.vogella.android.databinding.MainActivityPresenter"/>
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@={temp.celsius}"
            android:id="@+id/textView" />

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="@={temp.celsius}" />

        <Button
            android:text="Show data model"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="@{() -> presenter.onShowData(temp)}"
            android:id="@+id/button" />

    </LinearLayout>
</layout>

You see some warning messages in the editor, e.g., because you used hard-codes strings. We demonstrates later how to get rid of these warning messages.

package com.vogella.android.databinding;

import android.app.Activity;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.widget.Toast;

import com.vogella.android.databinding.databinding.ActivityMainBinding;

public class MainActivity extends Activity implements MainActivityContract.View {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        MainActivityPresenter mainActivityPresenter = new MainActivityPresenter(this);
        TemperatureData temperatureData = new TemperatureData("10");
        binding.setTemp(temperatureData);
        binding.setPresenter(mainActivityPresenter);
    }

    @Override
    public void showData(TemperatureData temperatureData) {
        String celsius = temperatureData.getCelsius();
        Toast.makeText(this, celsius, Toast.LENGTH_SHORT).show();
    }
}

Adjust your MainActivity code to activate data binding.

2.4. Validate your application

You can start your application in the emulator or use the layout review in your IDE. If you press the button, a small popup should be shown with the correct data.

The TextView should update automatically if you type in the EditText field.

3. About this website

4. Android databinding resources

4.1. vogella GmbH training and consulting support

TRAINING SERVICE & SUPPORT

The vogella company provides comprehensive training and education services from experts in the areas of Eclipse RCP, Android, Git, Java, Gradle and Spring. We offer both public and inhouse training. Whichever course you decide to take, you are guaranteed to experience what many before you refer to as “The best IT class I have ever attended”.

The vogella company offers expert consulting services, development support and coaching. Our customers range from Fortune 100 corporations to individual developers.

Copyright © 2012-2016 vogella GmbH. Free use of the software examples is granted under the terms of the EPL License. This tutorial is published under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Germany license.

See Licence.