Android data binding

Data Binding Library

The Data Binding Library allows you to bind UI components in your layouts to data sources in your app using a declarative format rather than programmatically.

Traditionally Layouts are defined :

findViewById<TextView>(R.id.sample_text).apply {
    text = viewModel.userName
}

Binding components in the layout file lets you remove many UI framework calls in your activities, making them simpler and easier to maintain. This can also improve your app’s performance and help prevent memory leaks and null pointer exceptions.

<TextView    
     android:text="@{viewmodel.userName}" />

Note the use of @{} syntax in the assignment expression:

To configure your app to use data binding, add the dataBinding element to your build.gradle file in the app module, as shown in the following example:

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

Layouts and binding expressions

The expression language allows you to write expressions that handle events dispatched by the views. The Data Binding Library automatically generates the classes required to bind the views in the layout with your data objects.

Data binding layout files are slightly different and start with a root tag of layout 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 following code shows a sample layout file:

<?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.

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

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

<TextView android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:text="@{user.firstName}" />

Data object

Let’s assume for now that you have a plain-old object to describe the User entity:

data class User(val firstName: String, val lastName: String)

This type of object has data that never changes. It is common in applications to have data that is read once and never changes thereafter. It is also possible to use an object that follows a set of conventions, such as the usage of accessor methods in Java, as shown in the following example:

// Not applicable in Kotlin.
data class User(val firstName: String, val lastName: String)

From the perspective of data binding, these two classes are equivalent. The expression @{user.firstName} used for the android:text attribute accesses the firstName field in the former class and the getFirstName() method in the latter class. Alternatively, it is also resolved to firstName() if that method exists.

Binding data

A binding class is generated for each layout file. By default, the name of the class is based on the name of the layout file, converting it to Pascal case and adding the Binding suffix to it. The above layout filename is activity_main.xml so the corresponding generated class is ActivityMainBinding. This class holds all the bindings from the layout properties (for example, the user variable) to the layout’s views and knows how to assign values for the binding expressions.The recommended method to create the bindings is to do it while inflating the layout, as shown in the following example:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

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

    binding.user = User("Test", "User")
}

At runtime, the app displays the Test user in the UI. Alternatively, you can get the view using a LayoutInflater, as shown in the following example:

val binding: ActivityMainBinding = ActivityMainBinding.inflate(getLayoutInflater())

If you are using data binding items inside a Fragment, ListView, or RecyclerView adapter, you may prefer to use the inflate() methods of the bindings classes or the DataBindingUtil class, as shown in the following code example:

val listItemBinding = ListItemBinding.inflate(layoutInflater, viewGroup, false)
// or
val listItemBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false)

About the author

admin

I am GD, I am full time Android Developer and Machine Learning Enthusiast. I like to learn and try my hands on new technologies and programming languages.

View all posts

Leave a Reply

Your email address will not be published. Required fields are marked *