Android Data Binding Part 2

We have seen basics of Data binding which covers following points:

  • How to set up data binding in Android?
  • How data binding makes findViewById obsolete?
  • How to bind data in layout file?

If you haven’t gone through it then please check Data Binding Part 1.

In this tutorial, we will see following points in Data Binding:

  • How can we change binding class name?
  • Event handling with Method references & Lambda expressions
  • Expression language of Data binding

Let’s start with first one,

How can we change binding class name?

  • By default, the binding class is generated based on the name of the layout file and placed in a data binding package under the module package. E.g. the layout file activity_login.xml will generate ActivityLoginBinding. If the module package is com.androidbytes.databindingdemo, then it will be placed in com.androidbytes.databindingdemo.databinding directory.
  • However, most of the developers prefer that the generated binding name should be LoginActivityBinding. So, it will be more readable.
  • Let’s see, how we can rename the binding class. All we have to do is adjusting the class attribute of the data tag in the layout file. Like following code:
<?xml version="1.0" encoding="utf-8"?>

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <data class="LoginActivityBinding">
            ...
    </data>
</layout>
  • Now generated binding class is named LoginActivityBinding.
  • And we can also change default package of generated binding class like following code:
<?xml version="1.0" encoding="utf-8"?>

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <data class="com.androidbytes.databindingdemo.LoginActivityBinding">
            ...
    </data>
</layout>
  • It will generate binding class in com.androidbytes.databindingdemo package. Pretty simple, right? Let’s see event handling.

Event handling with Method references & Lambda expressions?

Data binding also provides a way to bind events of view. View has some attributes which match with there event methods like View.OnClickListener has a onClick() method, View.OnLongClickListener has a onLongClick() method. So we can set bind view’s events from attributes like android:onClick, android:onLongClick and many more.

We can bind events using Method references and Listener binding. Check the following layout file:

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

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <data class="LoginActivityBinding">
        // Step 1
        <import type="android.view.View" />

        <import type="android.widget.EditText" />

        <variable
            name="loginHandler"
            type="com.androidbytes.databindingdemo.LoginHandler" />

    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="16dp"
        tools:context="com.androidbytes.databindingdemo.LoginActivity">

        <EditText
            android:id="@+id/edit_text_user_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Enter your email address"
            android:inputType="textEmailAddress" />

        <EditText
            android:id="@+id/edit_text_password"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Enter password"
            android:inputType="textPassword" />


        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/text_view_name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:layout_toLeftOf="@+id/check_box_show_password"
                android:gravity="center_vertical"
                android:text="@{editTextPassword.text}"
                // Step 6
                android:visibility="@{checkBoxShowPassword.checked ? View.VISIBLE: View.INVISIBLE}" />

            <CheckBox
                android:id="@+id/check_box_show_password"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                // Step 2
                android:onCheckedChanged="@{loginHandler::setPasswordVisible}"
                android:layout_alignParentRight="true"
                android:text="Show Password" />
        </RelativeLayout>


        <Button
            android:id="@+id/button_login"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            // Step 3
            android:onClick="@{(view) -> loginHandler.performLogin(editTextUserName.getText().toString(), editTextPassword.getText().toString())}"
            // Step 4
            android:background="@{buttonLogin.enabled ? @color/colorPrimaryDark : @android:color/black}"
            // Step 5
            android:enabled="@{!editTextUserName.getText().toString().isEmpty() &amp;&amp; !editTextPassword.getText().toString().isEmpty()}"
            android:text="Login"
            android:textColor="@android:color/white"
            android:textSize="18sp" />

    </LinearLayout>

</layout>

And check LoginHandler class which has methods which are directly bound to layout file.

public class LoginHandler {

    private final String TAG = "LoginHandler";

    public void performLogin(String userName, String password) {
        // Some magic code of login

        Log.d(TAG, "Username: " + userName + " & Password:" + password);
    }

    public void setPasswordVisible(View view, boolean isVisible) {

        Log.d(TAG, isVisible ? "Password is visible" : "Password is not visible");
    }
}

Let’s see what’s going on in activity_login.xml file.

Step 1:

Here, we have import android View class. Yes, you read it right. Data binding provides a way to import Android and Java class. So, we can use its static properties. Like, we have used in View.VISIBLE and View.INVISIBLE in Step 6.

Step 2:

@{loginHandler::setPasswordVisible} is an example of event binding with Method reference. We have bound a method of checkbox’s onCheckedChanged with handler’s setPasswordVisible. Signature of reference method will be same as signature of the listener method. Means here, setPasswordVisible has a same signature as onCheckedChanged.

Step 3:

It’s an example of event binding with Lambda expression. Whenever event is dispatched, listener evaluates the lambda expression and invoke bound method. In our case, button click will call handler’s performLogin method. That’s it in event handling. Now see 3rd and last point Expression language.

Expression language of Data binding

Expression language of Data binding almost looks like Java expression. We have also implemented in our activity_login.xml like:

Step 4:

I know I know, you already got it. It’s ternary operator expression in layout file.

Step 5:

It’s logical AND operator in layout file.

There are so many other operators that you can use in the layout. There is one operator named Null Coalescing Operator ?? which I would like to share:

android:text="@{address.landmark ?? address.areaCode}"

// both are technically same

android:text="@{address.landmark != null ? address.landmark : address.areaCode}"

You can check more on operators on Android Developer

I hope you liked the article. Feel free to share any feedback. And stay tuned for more on Data Binding!

Thanks for reading! Please share this article with others to spread knowledge.

Leave a Reply

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