Android Custom Data Binding Jetpack Component directly with XML View

Sharing is caring!

As an Android developer, we are familiar with data binding concept. Data binding is a library to bind the data model directly to XML view in an easy and flexible way. I have already written a basic article on the binding concept. I would recommend to please check this post How to bind the Data Model to View?

Now in this tutorial, we will try to learn new Jetpack component Data binding. I hope every one familiar with JetPack architecture Component has introduced by Google this year. Data Binding is one of a feature that comes under the JetPack Architecture Component. I have already posted an article about the evolution of JetPack architecture Component.

To use the Data Binding feature in our project we need to just enable the feature of data binding in android studio gradle file.

android {
  
    dataBinding {
        enabled true
    }

}

Bind Data Model directly to XML View:

This is a very basic binding concept, We can directly bind the data model to the XML view. We need to define the data model inside the data layer tag in XML and use this directly to XML of any view component. Let’s see an example to basic data binding data model to the XML view.

class MovieEntity{
    @SerializedName("id")
    var id: Int = 0

    @SerializedName("poster_path")
    var posterPath: String=""

    @SerializedName("adult")
    var isAdult: Boolean = false

    @SerializedName("overview")
    var overview: String? = null

    @SerializedName("original_title")
    var originalTitle: String? = null

    @SerializedName("title")
    var title: String? = null

}

This is a sample of the data model which are bind with the XML view.

<?xml version="1.0" encoding="utf-8"?>
<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>
        <variable
                name="movie"
                type="com.sunil.arch.data.MovieEntity"/>
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/item_home_root"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:clickable="true"
            android:focusable="true"
            tools:context=".ui.main.MainFragment">
        <ImageView
                android:layout_width="200dp"
                android:layout_height="200dp"
                tools:srcCompat="@tools:sample/avatars"
                android:id="@+id/imageView"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
                android:scaleType="fitXY"
                app:layout_constraintStart_toStartOf="parent"/>
        <TextView
                android:text="@{movie.title}"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/textView"
                app:layout_constraintBottom_toTopOf="@id/imageView"/>
    </androidx.constraintlayout.widget.ConstraintLayout>

As we can see the above XML tag <TextView>, we used android:text=”@{movie.title}” for binding the data model attribute title with the Textview.

Binding Adapters with a custom XML attribute :

The binding adapter has introduced in JetPack component with annotated with a @BindingAdapter component. For an example of the bind, the ImageView with Image Url attributes to load directly image with the help of glide library. For that first, We need to create the root object class and define the static function to bind with XML View. Here we need to use the annotated binding component name @BindingAdapter(“app:imageUrl”).

object MainBinding {

    @BindingAdapter("app:imageUrl")
    @JvmStatic
    fun loadImageUrl(view: ImageView, url: String) {
        Glide.with(view.context).load(url).into(view)
    }

}

Now we can directly use this tag name “app:imageUrl” in an ImageView component of an XML layout. In the function name loadImageUrl (view: ImageView, url: String),  the first method parameter is the type of target View and the second parameter is the value being set to the attribute.

<?xml version="1.0" encoding="utf-8"?>
<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>
        <variable
                name="movie"
                type="com.sunil.arch.data.MovieEntity"/>
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/item_home_root"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:clickable="true"
            android:focusable="true"
            tools:context=".ui.main.MainFragment">
        <ImageView
                android:layout_width="200dp"
                android:layout_height="200dp"
                tools:srcCompat="@tools:sample/avatars"
                android:id="@+id/imageView"
                app:imageUrl="@{@string/image_url_text(movie.posterPath)}"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
                android:scaleType="fitXY"
                app:layout_constraintStart_toStartOf="parent"/>
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

As we can see in above XML of  ImageView tag, We have used the app:imageUrl=”@{@string/image_url_text(movie.posterPath)}” as a custom BindingAdapter concept. Here I used the @string/image_url_text for pre appending the string with posterpath.

Binding Event Handler directly with XML.

Data Binding is not only providing the custom binding adapter and data model with XML but also for binding the Event handling also like Click on Any View Event. Let’s see an example of click listener binding.

class MainViewModel{
   
    fun userClicksOnItem(movieEntity: MovieEntity) =
        navigate(MainFragmentDirections.actionMainFragmentToDetailFragment(movieEntity))
}

MainViewModel class having an userClickonItem function to navigate the Main Fragment to Detail Fragment. So basically I want to click on a View to navigate the destination Fragment. In this case, we directly use this function of ViewModel inside the XML to handle the click Event.

<?xml version="1.0" encoding="utf-8"?>
<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>
        <variable
                name="movie"
                type="com.sunil.arch.data.MovieEntity"/>
        <variable
                name="viewmodel"
                type="com.sunil.arch.viewModel.MainViewModel"/>
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/item_home_root"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:clickable="true"
            android:focusable="true"
            android:onClick="@{() -> viewmodel.userClicksOnItem(movie)}"
            tools:context=".ui.main.MainFragment">
      
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

As we can see in above XML we used the onClick attribute ( android:onClick=”@{() -> viewmodel.userClicksOnItem(movie)}”) directly to handle the click Event to use the function to navigation. It makes the Click Event pretty simple and easy. For using the Data Binding Concept we can ignore the boilerplate code many places.

Binding To Setters of any Custom View Class:

Now Data Binding providing the bind with any Custom View Class member directly with the XML. Let’s see an example of a Custom View Class.

public class ColorPicker extends View {
    private int color;

    public void setColor(int color) {
        this.color = color;
        invalidate();
    }

    public int getColor() {
        return color;
    }
   
    //...
}

So Here I have View Class name ColorPicker which have the setter variable name color which we can bind the XML directly.

<com.example.myapp.ColorPicker
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:color="@{color}"/>

So basically the conclusion comes that why we need to write any complicated logic and code if the Data Binding makes simpler for Android. Now We can use benefits of awesome  Android Data Binding Feature many more places in our project.

Wrapping 

Now we have a good understanding of custom adapter Android Data Binding. We can play with few examples of Data Binding directly with XML.ou can get the full Github source code of Jetpack Sample. In my next tutorial, we will come with new technical stuff to discuss, ok till then enjoy your healthy day.

If you are wondering to learn Android then Please learn from Android category and wondering to learn Kotlin then Kotlin Category will help you. If you want to learn all the python article, then learn from the python category.

Happy Coding 🙂

 

0 0 votes
Article Rating
Android Custom Data Binding Jetpack Component directly with XML View
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Scroll to top
0
Would love your thoughts, please comment.x
()
x