cft

Android Data Binding

Layouts are often defined in activities with code that calls UI framework methods.


user

shashank mohabia

3 years ago | 5 min read

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

Layouts are often defined in activities with code that calls UI framework methods. For example, the code below calls findViewById() to find a TextView widget and bind it to the userName property of the viewModel variable:

findViewById<TextView>(R.id.sample_text).apply {
text = viewModel.userName
}// if you don't like findviewbyid you can use synthetic importssample_text.text = viewModel.username

The following example shows how to use the Data Binding Library to assign text to the widget directly in the layout file. This removes the need to call any of the code shown above. Note the use of @{} syntax in the assignment expression:

<TextView android: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.

Note: In many cases, view binding can provide the same benefits as data binding with simpler implementation and better performance. If you are using data binding primarily to replace findViewById() calls, consider using view binding instead.

Data binding has the following benefits:

  1. Code is shorter, easier to read, and easier to maintain than code that uses findByView().
  2. Data and views are clearly separated. This benefit of data binding becomes increasingly important later in this course.
  3. The Android system only traverses the view hierarchy once to get each view, and it happens during app startup, not at runtime when the user is interacting with the app.
  4. You get type safety for accessing views. (Type safety means that the compiler validates types while compiling, and it throws an error if you try to assign the wrong type to a variable.)

Let’s Get started

Let’s see how to get your development environment ready to work with the Data Binding Library, including support for data binding code in Android Studio.

Step 1. Enable data-binding:

To use data binding in our project we have to enable it in app level build.gradle file.

dataBinding {
enabled = true
}

Step 2. Change the layout file to be usable with data-binding:

The expression language allows you to write expressions that connect variables to the views in the layout. The Data Binding Library automatically generates the classes required to bind the views in the layout with your data objects. The library provides features such as imports, variables, and includes that you can use in your layouts.

For the layout to use data binding the topmost view in the layout should be <layout> view or in other terms, we have to wrap the entire layout in <layout> tag like this:

<layout>
<ConstraintLayout… /> <! - UI layout's root element →
</layout>

For using data from other classes or object we have to create a data object inside the layout file and declare that class or object’s variable in it.

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="user"
type="com.myapp.data.User" />
</data>
<ConstraintLayout… /> <! - UI layout's root element →
</layout>

To avoid errors all package names should start with the lowercase alphabet and all the data classes’ names should begin with the uppercase alphabet.

Step 3. Create a binding object in the activity/fragment:

Now its time to connect our layout to activity/fragment using data-binding.

Create a binding object in the file:
The type of binding is derived from the name of the layout file. e.g if the layout file’s name was activity_main.xml, then data-binding will create a class named ActivityMainBinding and this file will include all the required properties and functions.

private lateinit var binding: ActivityMainBindingorprivate lateinit var binding: FragmentGameBinding

Initialize the binding variable in the onCreate() method:

Now we have to initialize the binding and replace the existing setContentView () method. This can either be done by calling DataBindingUtil class or by directly using the binding type.

For activity binding type cannot be used.

//for activity (in onCreate())
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)//for fragment (in onCreateView())
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_game, container, false)orbinding = FragmentGameBinding.inflate(inflater)

Step 4. Use the binding object:

Now we can use the binding we created for two purposes:

  1. Replacing all the calls to findViewById or just the synthetic imports by binding.<view’s id>.

e.g if there is a text view in the layout with id sample_text, we must be using this in either of the two given ways

findViewById<TextView>(R.id.sample_text).apply{
text = "dummy text"
}or simply using synthetic importsample_text.text = "dummy_text"

Now this will be replaced by

binding.sampleText.text = "dummy_text"

Note the property name in the binding class is just the camelcase form of the view’s ID.
e.g sample_text becomes sampleText

2. Setting the variable declared in the data object in the layout and then using it in the layout file.

If the layout file has a variable named “user”

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="user"
type="com.myapp.data.User" />
</data>
<ConstraintLayout… /> <! - UI layout's root element →
</layout>

Then we have to set this in activity/fragment

binding.user = User()

And now we can use this for populating views data.

e.g if there a text view which displays the user’s name, then we can use @{} syntax to set the value.

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

In this way, we can avoid a lot of code to be done to set views programmatically and let data-binding take care of it.

Two-way data binding

In the previous section, we saw how we can get the values of properties and objects in the layout file. But data-binding also allows us to set values for these objects from the layout.

e.g if we have a form that requires data for user profile. In that case, the layout will have many edit texts and then we have to get their values in activity using binding (like binding.name_edittext.text) and this will increase redundant code and also we don’t see any advantage of using data-binding here.

But the truth is we can set the values in the same way we are getting the values. If we have the object as a variable in the layout file then its value can be set using @={} notation in the view. Using the above example:

<EditView 
...
android:text="@={user.userName}"
...
/>

This will set the value for the user object’s username.

Data-binding helps us in many other ways including binding adapters and many more. I will try to cover other benefits of it in a separate blog.

This article was originally published by Shashank Mohabia on medium.

Upvote


user
Created by

shashank mohabia


people
Post

Upvote

Downvote

Comment

Bookmark

Share


Related Articles