How to use Data Binding Android Library in Kotlin

 
This post shows step by step guide to use Data Binding library specially for RecyclerView using Kotlin in Android. You can checkout Sample App at HERE.
 

Data Binding Android Library is a support library that allows you to bind UI components in your layouts to data sources in your app using a declarative format rather than programmatically. This reduces lot of boilerplate code in your business logic that you usually write to sync the UI when new data is available.
 
Data Binding Android Library allows developers to maintain code easily with the help of binding components in layout file. If you want to learn how to integrate retrofit library in android app then you can refer this article.
 
 

Enabling DataBinding in build.gradle under app module

apply plugin: 'kotlin-kapt'

android {
    dataBinding {
        enabled true
    }
}
dependencies {
    implementation 'com.android.support:recyclerview-v7:27.1.1'
    implementation 'com.android.support:cardview-v7:27.1.1'
}

 

Create a POJO class

package com.example.databindingdemo.models

data class Player(val name:String, val club: String, val country: String)

 

Convert your layout in DataBinding layout

To enable DataBinding in a layout, the root element must start with the <Layout> tag. With this, the <data> and <variable> tags are used.

<?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">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler_main"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:paddingTop="15dp"/>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Binding layout with data

  1. A <data> tag follows <Layout>. All binding variables and methods must go inside the <data> tag.
  2. Inside the <data> tag, a variable will be declared using the <variable> tag. The variable tag takes two attributes `name` and `type`. The name attribute will be the alias name and type must be of object model class. In our case, the path of the user class.
  3. To bind a value, the @ annotation must be used. In the layout below, the player name, player club and player country are bound to the TextView using @ {Player.name}, @ {Player.club} and @ {Player.country}
<?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">

    <data>
    <variable
        name="Player"
        type="com.example.databindingdemo.models.Player" />
    </data>

        <androidx.cardview.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="15dp"
            app:cardCornerRadius="10dp">

            <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="15dp">

                <TextView
                    android:id="@+id/txt_player_name"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@{Player.name}"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    android:textSize="25sp"
                    android:textStyle="bold"/>

                <TextView
                    android:id="@+id/txt_player_info"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@{Player.club + ` | ` + Player.country}"
                    app:layout_constraintTop_toBottomOf="@+id/txt_player_name"
                    app:layout_constraintStart_toStartOf="parent"
                    android:textSize="20sp"/>

            </androidx.constraintlayout.widget.ConstraintLayout>

        </androidx.cardview.widget.CardView>

</layout>

 

Make changes in adapter

package com.example.databindingdemo.adapters

import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import com.example.databindingdemo.R
import com.example.databindingdemo.databinding.PlayerRowBinding
import com.example.databindingdemo.models.Player

class PlayerAdapter(private val context: Context, private val list: MutableList<Player>?) : RecyclerView.Adapter<PlayerAdapter.MyViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val inflater = LayoutInflater.from(context)
        val binding: PlayerRowBinding = DataBindingUtil.inflate(inflater, R.layout.player_row,parent,false)
        return MyViewHolder(binding)
    }

    override fun getItemCount(): Int {
        if(list == null){
            return 0
        }
        return list.size
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        holder.itemBinding.player = list?.get(position)
    }

    class MyViewHolder(val itemBinding: PlayerRowBinding) : RecyclerView.ViewHolder(itemBinding.root){

        private var binding : PlayerRowBinding? = null

        init {
            this.binding = itemBinding
        }

    }

}


Make changes in Activity

A binding class is generated for each layout file in DataBinding. By default, the class name is based on the name of the layout file, converting it to the Pascal case and adding the binding suffix to it. For layout activity_main.xml, the generated binding class activity will be ActivityMainBinding.
 
 
package com.example.databindingdemo.activities

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.databindingdemo.R
import com.example.databindingdemo.adapters.PlayerAdapter
import com.example.databindingdemo.databinding.ActivityMainBinding
import com.example.databindingdemo.models.Player

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val binding: ActivityMainBinding = DataBindingUtil.setContentView(this@MainActivity, R.layout.activity_main)
        binding.recyclerMain.layoutManager = LinearLayoutManager(this@MainActivity)

        val playersList = mutableListOf<Player>()
        playersList.add(Player("Cristiano Ronaldo","Juventus","Portugal"))
        playersList.add(Player("Thiago Silva","PSG","Brazil"))
        playersList.add(Player("Sergio Ramos","Real Madrid","Spain"))

        val adapter = PlayerAdapter(this,
            playersList
        )
        binding.recyclerMain.adapter = adapter

    }
}

data binding android

4 thoughts on “How to use Data Binding Android Library in Kotlin

Leave a Reply