Android: Working with DataBinding

in #utopian-io7 years ago (edited)

Android-HD-Desktop-Wallpaper.jpg

What I am going to learn?

You will learn how to use Data Binding library in order to minimize the glue code used to bind your application logic with your layout.


After this tutorial you will know:

  • How to set up your data binding library
  • How to define your model
  • How to bind your data with your layout

Requirements

Going trough this tutorial I am assuming that you already know:

  • How to use Android Studio.
  • How to create a simple app.
  • How to create and inflate layouts.

Difficulty

  • Basic

Get Started

Data Binding it's a cool feature provided by Android guys which can replace the ugly lines of code used to inflate your layout elements. Also it can replace Butter Knife.
The advantage of using Data Binding is not only writing less code, but having flexibility and building a modular application. In the next tutorials I am going to talk about MVVM pattern and how can be used with Live Data and Data Binding.
With these three tools you will be able to create great applications with less code and fewest bugs.
But for know let's talk about Data Binding.


Set up your data binding

To be able to use data binding, the application should know about it. Surprisingly it's easiest than you think to import data binding library. Assuming that you already updated your Support Repository from Android SDK Manager, all you need to do is to go to build.gradle file from your application and add this line of code:

dataBinding
{
        enabled = true
    }

That's it! Let's go forward.


Writing your first data binding expression

When you create a layout, an xml file is generated with a root element. Like this:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android";
    xmlns:app="http://schemas.android.com/apk/res-auto";
    xmlns:tools="http://schemas.android.com/tools">;
//your elements will come here
</LinearLayout>

Data binding layouts are a little bit different, starting with the <layout> tag. Inside this tag, we will add <data> element followed by the root element, in our case will be <LinearLayout>
A simple code will look like this:

<layout xmlns:android="http://schemas.android.com/apk/res/android";
    xmlns:app="http://schemas.android.com/apk/res-auto";
    xmlns:tools="http://schemas.android.com/tools">;
    <data>
        <import type="android.view.View" />
        <variable
            name="user"
            type="com.adabinding.databinding.pojo.User" />
    </data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:layout_margin="20dp"
        android:gravity="center_vertical"
        >
       <TextView
           android:id="@+id/title"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:text="@string/title"
           android:textSize="@dimen/title_size"
           android:gravity="center"
           android:textStyle="bold"
           android:layout_marginBottom="@dimen/margin_title"
           />
</LinearLayout>
</layout>

As you can see, inside <data> tag we have user variable which is used as a property within layout.
The expression written in the attribute property is looking like this:
"@{}"
It looks complicated but it's not. I will show you latter in this post how to define it.
Bellow variable name which is user in our case, we need to specify the variable type. You can use any object as type. In our example we've created a simple POJO object called User with four properties: name, address, phone and email. These four properties will be used in our layout with the "@{}" syntax.

    private final String name;
    private final String address;
    private final String phoneNumber;
    private final String email;
    public User(String name, String address, String phoneNumber, String email) {
        this.name = name;
        this.address = address;
        this.phoneNumber = phoneNumber;
        this.email = email;
    }
    public String getName() {
        return name;
    }
    public String getAddress() {
        return address;
    }
    public String getPhoneNumber() {
        return phoneNumber;
    }
    public String getEmail() {
        return email;
    }
}

Let's go back in our layout, add four TextView elements and User data for setting the properties.

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:layout_margin="20dp"
        android:gravity="center_vertical"
        >
       <TextView
           android:id="@+id/title"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:text="@string/title"
           android:textSize="@dimen/title_size"
           android:gravity="center"
           android:textStyle="bold"
           android:layout_marginBottom="@dimen/margin_title"
           />
        <TextView
            android:id="@+id/user_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{user.name}"
            tools:text="Jack"
            android:textAlignment="center"
            />
        <TextView
            android:id="@+id/address"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{user.address}"
            tools:text="USA, Str. South Congress, No. 234A"
            android:textAlignment="center"
            />
        <TextView
            android:id="@+id/phoneNumber"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{user.phoneNumber}"
            tools:text="+349788390298"
            android:textAlignment="center"
            />
        <TextView
            android:id="@+id/email_address"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{user.email}"
            tools:text="[email protected]"
            android:textAlignment="center"
            />
        <Button
            android:id="@+id/done"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="@{handler::onClickDone}"
            android:text="@string/done"
            android:layout_marginLeft="@dimen/button_margin"
            android:layout_marginRight="@dimen/button_margin"
            android:layout_marginTop="@dimen/button_margin_top"
            />
    </LinearLayout>

As you can see, the expression "@{user.name}" is used for the TextView's attribute android:text which will access getName() property from User object. In the same way we will do for the next three texts: address, phone and email.
Another cool thing you can do with data binding is to declare a listener for elements which uses user's action. In our example, we have a button which will use the onClick attribute to set the behavior when the user will tap on it.
To be able to use data binding all we need is adding another variable inside <data> tags.
In our case will be :

<variable
            name="handler"
            type="com.adabinding.databinding.handlers.UserHandler"/>

As you can see, we set as a type a handler which is a simple interface with a callback method:

public interface UserHandler {
    void onClickDone(View view);}

After declaring the variable we need to use it in Button attribute.

android:onClick="@{handler::onClickDone}"

When the user will press the button, handler.onClickDone() method will be called.


Binding Data

We are done with the layout. Let's bind data in activtiy. In our onCreate method write the following code:

//        setContentView(R.layout.activity_main);
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        User user = new User("John Doe",
                "USA, Str. South Congress, No. 234A",
                "+345898374930",
                "[email protected]");
        mBinding.setUser(user);
        mBinding.setHandler(this);

Using data binding, we will replace the setContentView(R.layout.activity_main); line with mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
By default a binding class will be generated based on the name of the layout file. In our case the layout name is activity_main so the binding object will be :

  private ActivityMainBinding mBinding;

After initialize data binding, all we need to do is to create our User object:

User user = new User("John Doe",
                "USA, Str. South Congress, No. 234A",
                "+345898374930",
                "[email protected]");

And to set it on binding with

mBinding.setUser(user);

Two more things and we are ready.

  • Implement and override the onClickDone method
    public void onClickDone(View view) {
        Toast.makeText(this, "Done button clicked", Toast.LENGTH_LONG).show();
    }
  • Set the handler defined in layout with
mBinding.setHandler(this);

Running the application

We are ready to run our application :)
This is the result:

databinding.gif

You can find the source code here

If you have any questions, please comment below.

Thank you for your time and see you next time.

If you want to receive more updates like this, please upvote and follow me.


Proof of work

proofofwork.gif
;



Posted on Utopian.io - Rewarding Open Source Contributors

Sort:  

Wish I had done this back when I had an Android Phone :D

What happened with your Android phone? :) It's a great way to have a cleaner code. Also when used with LIveData and MVVM pattern, it's a pleasure to create Android Applications :)

Your contribution cannot be approved because it does not follow the Utopian Rules.

My Opinion:

  • Wrong repository.
  • There is similarly well documented information on the internet about Android DataBinding.

You can contact us on Discord.
[utopian-moderator]

@portugalcoin what do you mean by wrong repository?