Data Binding for Android Beginners—part 1

Tobiloba Adejumo
MindOrks
Published in
7 min readMar 2, 2019

This article is the second part of the series, Data Binding for Android Beginners. If you did not read the previous one, you can start from here.

Series Intermission

  • Data Binding for Android Beginners — Introduction
  • Data Binding for Android Beginners — DB part 1 (you are here)
  • Data Binding for Android Beginners — DB part 2
  • Data Binding for Android Beginners — Custom Binding
  • Data Binding for Android Beginners — Advanced Binding Operations.
  • Data Binding or Android Beginners — Custom Views with Binding

Previously on Data Binding…

In our last intermission, we discussed about the main purpose of data binding, how to enable data binding in your application and also when your layout is properly created for data binding.

Prerequisites

I assume you are familiar with inflating views from activities, Java programming, OOP concepts and Android development.

How can we make use of Data Binding in scalable applications?

Because of its robustness in binding data neatly in our applications, data binding can be used selectively in our applications. You might choose to use data binding in a layout file, and also choose to completely avoid it in another layout when it becomes difficult and very confusing to manage. I avoid it sometimes too :).

As developers, the first thing you should know about the practical usage of data binding is either in a signup activity or login activity. This article teaches you a very clear, concise and easy way of implementing data binding in a simple login application without bringing the extra fluff of MVP pattern or MVVM pattern that some developers battle with.

A sample login app.

Project Breakdown

The application consists of three EditText widgets (first name, last name and password) and a Button widget (login). When the EditText widgets are empty, the button will be grayed out, the button clickable property will be disabled and the text color will be set to black. Similarly, when the EditText widgets are not empty, the button will be set to blue, the button text color will be set to white and the button clickable property will be enabled. The source code to this project is available here.

Steps to Accomplish this Without Using the Traditional findViewById()

  • Prepare your layout for data binding.
  • Bind the generated class to your layout
  • Create a model class or POJO (Plain Old Java Object)
  • Make the model class smart :)
  • Bind the values of the model class in the layout xml file.
  • Create an handler for button click action.
  • Bind the handler to the layout xml file.
  • Set the model and handler to the generated activity
  • Perform necessary layout checks.

#Prepare your Layout for Data Binding

  • Enable data binding in app build.gradle file.
  • Wrap the viewgroup of the layout to be binded with the layout tag
  • Specify the name of the generated class of your choice: If you do not specify this, the camel case of your layout file is generated then appended with ‘binding’. To specify the generated file, you make use of a class attribute. The class attribute should be used in the data tag. In this example, I want my generated class to be LoginActivityBinding. If you do not understand, please refer to my previous article.

#Bind the Generated Class to your Layout

  • This is done by inflating the layout using the Data Binding Util class. The Data Binding Util class is a generated class.

Extra Tip: The generated binding class knows all your widgets in your layout offhand without looking at your layout file. It is that powerful. :)

#Create the model or POJO class

  • Let the model class contain the properties that represents the needed views in the layout xml file.

#Make the Model class smart :)

How can we make the model class smart? In other words, a person is said to be smart when he or she is observable — ability to see, hear and respond to changes in the environment without being told to do so. Unfortunately, model class is not a person but still, as smart as a person. A smart model class has the ability to see the changes and constantly react to those changes by updating necessary layout components.

TL:DR

George Mount, a software engineer at Google explained this extensively in his article. The most open way of making your model class smart is by the model class

  1. Implementing Observable interface.
  2. Extending the BaseObservable class. The BaseObservable class already implements the Observable interface.
  3. Defining the properties of the class as a final ObservableField rather than the default primitive types. For instance, ObservableInt, ObservableField<String> or using ObservableMap when the data format is not yet known.

In this project, I’ll be extending the BaseObservable class, observing the getters of the properties in the model class with @Bindable annotation and notifying the change on the setters using the notifyPropertyChanged() methods. The @Bindable annotation generates the ID’s of the properties of the model class in the BR class which is similar to R class in java that contains generated the ID’s of the resources used in the application. These generated ID’s are passed as an argument to the notifyPropertyChanged() method.

#Bind the values of the model class in the layout xml file.

TL:DR

In data binding, there are two types of binding: one-way binding and two-way binding. In one-way binding, the server sends the data to the model object and the model object sends the data to the layout xml views. In two-way binding, the server sends the data to the model object, the object sends the data to the layout xml views and the layout xml has the ability to send back to the object data. So you see, in two-way binding, the model object can receive data from the server and from the layout.

Because we are using an EditText and there is a need to send the data entered by the user to the model object, we will be making use of two-way binding.

For binding, we need to include the variable tag in our layout. The variable tag contains the name attribute and type attribute. The name attribute contains an alias (any name of your choice) that is used to identify the type. The type contains the class to be binded to the layout, and yes you can have more than one variable tag in your layout file. The variable tag is nested in the data tag.

What property are we trying to bind again? — The text property of EditText text. Is there a tag already available? — Yes, the android:text tag is used to set text.

Next, in one-way binding, it is done this way: @{variableName.method}

In two-way binding, it is done this way: @={variableName.method}

Extra Tip: Please note that the layout only has access to public methods or public properties in your model class. So if the properties of in your model class are declared as private, it is advisable there is a public getter method defined so it can be used with data binding.

#Create an handler for button click action.

In the LoginHandler class, I created a method buttonLoginClick. You know, anytime android:onclick tag is used in our layout, a method is always defined in our activity that takes the View parameter. User model is injected to the LoginHandler class as the variables will be set in the LoginActivity class which contains the binded layout.

#Bind the handler to the layout xml file

  • Add a variable tag that contains the name attribute and the type attribute.
  • Use the already defined android:onClick tag in android namespace to set the buttonLoginClick() method in LoginHandler. (Remember, one way binding, layout is not sending data:))

Why use :: instead of . ?

Did you notice android:onClick = “@{handler::buttonLoginClick}” ?

“::” is used to reference a method in the model object.

“.” is used to reference properties in the model object.

#Set the model and handler to the generated activity

Follow through with the comments in the code. Also note the order.

#Perform necessary layout checks

We don’t want the user to proceed to the next screen when any of the EditText widgets is empty. We are going to do this with data binding.

TL:DR

The boolean checkInput() method is defined in my POJO class. When you application starts for the first time, the values of firstName, lastName and password returns null. It then sets the boolean checkInput method to false which means there are not inputs. Unless the three fields are not empty before true is returned to the checkInput method.

Similarly in our layout file, there is no need to make use of custom tag as all the needed tags are defined in the android namespace. The android:clickable, android:background and android:textColor tags are what we need to perform the manipulation.

RESULT

What’s Next?

On the next intermission, we’ll be walking through more deeper concepts in data binding, recyclerview implementation and also the need to create custom views with data binding.

Plus, check out my other stories.

Recommended Reading

Thank you for reading. 👏 I really hope you’ve found this article helpful. Your claps are really appreciated to help others find this article 😃 .

--

--

Tobiloba Adejumo
MindOrks

Interested in biomarker development, software dev and ai, as well as psychology, history, philosophy, relationships. Website: tobilobaadejumo.com