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
- A <data> tag follows <Layout>. All binding variables and methods must go inside the <data> tag.
- 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.
- 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 } }
Nice article in kotlin
Great article
Easy to understand
Awesome data binding sample in kotlin…