photo taken from www.mobikul.com

Android Data binding

Nishikanto Sarkar
Published in
6 min readFeb 28, 2018

--

Initiating data binding

I have recently learned android data binding. After learning it, I realized that I should have learned it earlier. You know why? Because using data binding can make your code more readable, less coding and also smart looking. I also found out that the documentation of android data binding is not so understandable. So I thought, I should write a short story about how to get started with android data binding.

Recently I’ve made an android app where I had to use 25 fields in one activity. I know this is not a good approach for UI design. But for some reason, I had to do that. So here come all the findViewbyIds, And it’s really a pain that why I should write so many unnecessary findViewByIds. Here I could use Butterknife instead of using findViewByIds but that’s not enough. Because I still have to identify the elements by using their ids on the XML.

No more talking. let’s get started with the basics of data binding. I will assume that you already know the basics android development. So I will go straight to data binding. In this story, we will make a login view using data binding.
First, we need to enable the data binding in app-level build.gradle. Add this block of code to build.gradle and your application is ready to use data binding.

dataBinding {
enabled = true
}

now we will create our view.

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

<data>

</data>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:gravity="center"
android:layout_height="match_parent"
tools:context="com.infancyit.newtestproject.main_activity.MainActivity">

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

<EditText
android:layout_marginBottom="20dp"
android:hint="User Name"
android:layout_width="150dp"
android:layout_height="wrap_content" />

<EditText
android:layout_marginBottom="20dp"
android:hint="password"
android:layout_width="150dp"
android:layout_height="wrap_content" />

<Button
android:layout_marginTop="20dp"
android:text="Login"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</LinearLayout>

</LinearLayout>

</layout>

In our login view, we just have three fields. two Edittext and one Button. we will give no id here. because we won’t need any ids. Well, you probably thinking where did the <layout> and <data> tag come from? These two tags will allow you to bind your views with the java code.

Now we have to create a java class which is called the view model. You can name it LoginViewModel. Now lets put some code in the <data> tag.

<data>
<variable
name="loginViewModel"
type="com.infancyit.newtestproject.main_activity.LoginViewModel"/>
</data>

Now you can see there is a new tag called variable. Well, this LoginViewModel class will bind with our view. so it’s like a variable for this view. We will go details about <data> tag in another chapter. our variable tag has two fields called name and type. In the name field, we can use any name. But, it’s better to use the class name with the 1st letter in lowercase like a variable naming conventions. And, in the type field, we have to give the location of the class.

After that, lets put some codes in our MainActvity’s onCreate() method. this few line will initiate your view and binding class.

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

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

LoginViewModel loginViewModel = new LoginViewModel();
binding.setLoginViewModel(loginViewModel);

}

In data binding, we will set our content view with a different style. In the above code block, you can see there is a new class called “ActivityMainBinding”. This class is auto-generated from the “activity_main.xml”. This class only gets generated when you use the <layout> tag as a parent of your layout.

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

This line will set the content view to the main activity class. And we get a binding instance. which will use to set the variable that we put in the <data> tag in our main_activity.xml layout.

LoginViewModel loginViewModel = new LoginViewModel();
binding.setLoginViewModel(loginViewModel);

Our binding instance has an auto-generated method called setLoginViewModel(). So first we create an instance of our class LoginViewModel. Then, pass this instance to the parameter of setLoginViewModel() method.

Now we will see how to use those fields in our view without using findViewByIds.

Using data binding

At first lets declare two variable in the LoginViewModel class.

public class LoginViewModel {

private String name;
private String password;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}
}

We need this getter setter method for accessing this variable from the layout. And now the fun part will begin. We are gonna bind this two variable with our views.

<EditText
android:layout_marginBottom="20dp"
android:hint="User Name"
android:text="@{loginViewModel.name}"
android:layout_width="150dp"
android:layout_height="wrap_content" />

<EditText
android:layout_marginBottom="20dp"
android:hint="password"
android:text="@{loginViewModel.password}"
android:layout_width="150dp"
android:layout_height="wrap_content" />

This two bold line will do the magic of data binding. when (name and password) those variable gets the value the views will immediately get that value too. We don’t have to set directly set anything to the view. We just have to set data to the model and our views will get those values from the model directly.

Here we have two EditText. So we need two-way binding. But first, let me tell about this one-way binding and two-way binding.

One way binding

One way binding means our views will get value from our model’s variable. For example, we have a TextView. Now TextView is not an input field. We just set a text to the TextView. So this just one way binding with models.

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

So all the views or fields those are not input fileds will use one way binding.

Two way binding

In EditText The view gets data from the user or from the model. Because it’s an input field so we will need two-way binding here. When user type anything in the EditText our model’s variable immediately gets those text. Like we don’t have to get the text with getText() method. isn’t it cool? So for two way binding, we have just added an equal sign(=) after the @ sign.

<EditText
android:layout_marginBottom="20dp"
android:hint="User Name"
android:text="@={loginViewModel.name}"
android:layout_width="150dp"
android:layout_height="wrap_content" />

<EditText
android:layout_marginBottom="20dp"
android:hint="password"
android:text="@={loginViewModel.password}"
android:layout_width="150dp"
android:layout_height="wrap_content" />

and also we will see the other features that binding provides us. So our fields are ready to use. But there is one problem. In our LoginViewModel class, we declare two fields as string type. But in two binding we need to us a new type of fields called observable. And also initialize those fields in the constructor.

public class LoginViewModel {

private ObservableField<String> name;
private ObservableField<String> password;

public void onLoginButtonClick(){
name = new ObservableField<>();
password = new ObservableField<>();
}

public ObservableField<String> getName() {
return name;
}

public ObservableField<String> getPassword() {
return password;
}

public void setName(ObservableField<String> name) {
this.name = name;
}

public void setPassword(ObservableField<String> password) {
this.password = password;
}
}

Now we are good to go.

Setting on click listener

Now we have to set on click listener to our login button. Like above we will use data binding for our button too. So we don’t need any id for our button too. just have to add one line to the button views.

<Button
android:layout_marginTop="20dp"
android:text="Login"
android:onClick="@{()->loginViewModel.onLoginButtonClick()}"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

And create a method named onLoginButtonClick() in the LoginViewModel Class. That’s all. our data binding is complete.

public void onLoginButtonClick(){

}

Here we use LoginViewModel class for everything. but if you want you can create another class for setting the click listener to the button or making the HTTP request. It’s your choice. You just have to add another variable to your layout. and also set the class in onCreate() in the activity class.

There is a lot more in data binding. I will suggest you look android developer documentation and find more feature of data binding. In future, I will try to write about Listview Data binding. Thank you for reading my story. If you like don’t forget to clap.

--

--

InfancyIT
InfancyIT

Published in InfancyIT

InfancyIT is a software company providing consulting and software solution services. We help our clients to grow their respective businesses by automating their daily tasks.