Oct 12 2016

Android Data Binding with MVVM

by Adam Podsiadło

Android Two-Way

In working with mobile applications, a primary concern should always be clean architecture with separated layers. The first layer is Data Persistence which is responsible for fetching data from the internet or from local device storage. The second layer connects data with an interactive presentation: User Interface. Some of the well known architectures, such as MVC, MVP, MVVM, exist to elevate the separation of concerns between the data and UI. Following a known architecture means implementing SOLID principles in a structured way.

At Google I/O in 2015, Android team presented a new data binding support library. This was a new cool thing that reduced the boilerplate code not only for performing view inflation, but also for setting and getting values from views.  Android Data Binding also allowed developers to streamline MVVM architecture easier.

Let’s check how it works on the example below to be more aware of the advantages that go with data binding. 

Set up Data Binding

Android data binding is an Android Studio IDE built-in feature, and it’s compatible for all Android versions since API 7. The only requirement is to have Gradle 1.5.0-alpha1 or higher version, but you should be good to go if you have a latest version of Android Studio. We enable the data binding in our gradle file: 

android {
    compileSdkVersion 24
    buildToolsVersion "24.0.0"
    dataBinding.enabled = true
}

Let’s use an MVVM approach and create a Model for our binding. 

Android data binding allows us to make reference in the XML layout to the fields in Java class. To connect our object fields and present its data we need to create a class like below:

public class CustomObject extends BaseObservable {
   public final ObservableField<String> label = new ObservableField<>();
   public final ObservableField<String> value = new ObservableField<>();
 
   public CustomObject(String label, String value) {
    this.label = label;
    this.value= value;
   }
}

Our class needs to extend BaseObservable, which provides a data binding interface for accessing ObservableFields in the layout file. ObservableField is primitive container for objects that informs us about changes of its value. This can be helpful while creating some custom converters using BindingAdapters

Connecting the Model with XML layout

Creating XML layout works differently with the data binding. The XML layout contains only one child: layout tag. The layout tag should have data tag as its first child, followed by a series of Android UI children. In the data tag, we include the java path to our model and ViewModel classes. In the Android UI tags, we use a data binding expression denoted by @{expression} for controlling actions in the view, click event listener, user input, etc..

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="model"
    type="com.your.package.CustomObject" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/label"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{model.label}" />

        <EditText
            android:id="@+id/value"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@={model.value}" />
    </LinearLayout>
</layout>

Data in our layout will use CustomModel, and we will connect both labels and values to views. In order to achieve this, we need to create a data binding variable with the application package path .CustomModel as a variable type.

To connect ObservableField to the layout we need to use @{}> or @={} for two-way data binding. Two-way binding means simply that our field will be updated whenever the value changes programmatically or by user input.

Connecting Model object with layout binding.

Now it’s time to connect our model to the layout and let the binding magic happen! In order to do that, we need to assign our object to binding reference auto-generated by Android. When we create a data-binding XML layout, Android Studio automatically creates a binding java object for us, denoted by the XML layout name. In this case, we name it ‘MyLayoutBinding’:

MyLayoutBinding myLayoutBinding = MyLayoutBinding.inflate(inflater);

CustomObject customObject = new CustomObject(‘my label’, my value’);
myLayoutBinding.setModel(customObject);

And that’s it! Now every time you type something in EditText our ‘value’ will update itself thanks to two-way data binding.

Some facts

This article just shows the very basics of what the new Android Data Binding can do, and how this can save not only time but also lines of boilerplate code. Less code will create a more readable architecture for the project, which will be easier for other developers to follow. For more details I encourage to you check out the Android docs for data binding 

Want more? Head back to the Tivix blog