Android JetPack Components ?

Deepak Sikka
5 min readOct 19, 2021

Android Jetpack is a set of software components, libraries, tools, and guidance to help in developing robust Android applications. Launched by Google in 2018.

This article explains each and every library of this component in detail. Jetpack consist of a wide collection of libraries that are built in a way to work together and make robust mobile applications

Architecture Components could be classified as follows:

  1. Room
  2. WorkManager
  3. Lifecycle
  4. ViewModel
  5. LiveData
  6. Navigation
  7. Paging
  8. Data Binding

We will start from Data Binding Library :

Data Binding is pre-android Jetpack library & interduce in (api level 23) in year 2015 and it is also backward compatibile with (api level 14).

The Data Binding 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.

To configure your app to use data binding, enable the dataBinding build option in your build.gradle file in the app module, as shown in the following example:

android {
buildFeatures {
dataBinding true
}
}

For example, the code below calls findViewById() to find a TextView widget and bind it to the userName property of the viewModel variable:

findViewById<TextView>(R.id.sample_text).apply {
text = viewModel.userName
}

The following example shows how to use the Data Binding Library to assign text to the widget directly in the layout file. This removes the need to call any of the Java code shown above. Note the use of @{} syntax in the assignment expression or binding expression:

<TextView
android:text="@{viewmodel.userName}" />

Layouts and binding expressions

The Data Binding Library automatically generates the classes required to bind the views in the layout with your data objects.Data binding layout files are slightly different and start with a root tag of layout followed by a data element and a view root element. This view element is what your root would be in a non-binding layout file. The following code shows a sample layout file:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.lastName}"/>
</LinearLayout>
</layout>

If you wants to set place holder to textview or you wants to change automatically generates class name than you can use below code:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data class ="UserInfoActivity">
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName,default='Place Holder'}"/>
</LinearLayout>
</layout>

Binding data

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

val binding:ActivityMainBinding = DataBindingUtil.setContentView(
this, R.layout.activity_main)

binding.user = User("Test", "User")
}

Data Binding for Include Layouts :

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="user"
type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName, default='Default_value'}"/>
<include android:id="@+id/include_layout"
layout="@layout/layout_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
bind:secondViewModel="{@user}"/>
</LinearLayout>
</layout>

layout_second

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="secondViewModel"
type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{secondViewModel.lastName,default='Default_value2'}"
</TextView>
</LinearLayout>
</layout>

Binding Fragment with Data Binding with live Example:

data class Product(
val productId:String,
val productName:String,
val description:String,
val price:Double,
val rating:Float,
val image:String
)

DataProvider.kt

import java.util.*

object DataProvider {
val productList: MutableList<Product> = ArrayList()
val productMap: MutableMap<String, Product> = HashMap()

// @itemId is used for image value as well
private fun addProduct(itemId: String, name: String,
description:String, price:Double,rating:Float) {

val item = Product(itemId, name, description, price, rating,"$itemId.png")
productList.add(item)
productMap[itemId] = item
}

init {
addProduct("shirt101","Cross-back training tank",
"Our cross-back training tank is made from organic.",
35.0, 4.0F)
addProduct("jacket101","Bamboo thermal ski coat",
"You’ll be the most environmentally.",
128.0,3.5F)
}
}

ViewModel

class MainViewModel(application: Application) :  AndroidViewModel(application) {

private var product = DataProvider.productList.get(1)
fun getProduct(): Product = product
}

Fragment

class MainFragment : Fragment() {

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {

val binding = FragmentMainBinding.inflate(inflater,container,false)

val viewModel =ViewModelProviders.of(this).get(MainViewModel::class.java)

binding.product = viewModel.getProduct()

setData(binding.root, viewModel.getProduct())

return binding.root

}
private fun setData(rootView: View, product: Product) {
rootView.iv_product_sale.visibility = if (product.salePrice > 0.0) View.VISIBLE else View.GONE
rootView.iv_product.setImageBitmap(getBitmapFromAssets(product.image))
}
private fun getBitmapFromAssets(fileName: String): Bitmap? {
return try { BitmapFactory.decodeStream(context?.assets?.open(fileName))
} catch (e: IOException) {
e.printStackTrace()
null
}
}
}

fragment_main.xml

<?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="product"
type="com.databindingexample.model.Product" />
</data>

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

<ImageView
android:id="@+id/iv_product_sale"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/sale_image"
app:layout_constraintBottom_toTopOf="@id/iv_product"
app:layout_constraintLeft_toLeftOf="@id/iv_product"
app:layout_constraintTop_toTopOf="@+id/iv_product" />

<ImageView
android:id="@+id/iv_product"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:src="@drawable/vest101"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_name" />

<RatingBar
android:id="@+id/rating_bar"
style="?android:attr/ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:rating="@{product.rating}"
app:layout_constraintBottom_toBottomOf="@+id/tv_price"
app:layout_constraintEnd_toStartOf="@id/tv_num_rating"
app:layout_constraintTop_toBottomOf="@+id/iv_product" />

<ScrollView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_below="@+id/tv_price"
android:layout_margin="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_price"
app:layout_constraintVertical_bias="0">

<TextView
android:id="@+id/tv_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="@{product.description}"
android:textSize="20sp" />

</ScrollView>

<TextView
android:id="@+id/tv_num_rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="50dp"
android:text="@{String.valueOf(product.totalRatings)}"
app:layout_constraintBottom_toBottomOf="@id/rating_bar"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/rating_bar" />

<TextView
android:id="@+id/tv_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_name"
android:layout_marginStart="50dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:gravity="center"
android:text="@{String.valueOf(product.price)}"
android:textSize="20sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/iv_product" />

<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@{product.name}"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:textSize="30sp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

</layout>

Using Imports in Data Binding

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

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

<ImageView
android:id="@+id/iv_product_sale"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/sale_image"
android:visibility="@{product.salePrice >0 ? View.VISIBLE : View.GONE}"
app:layout_constraintBottom_toTopOf="@id/iv_product"
app:layout_constraintLeft_toLeftOf="@id/iv_product"
app:layout_constraintTop_toTopOf="@+id/iv_product" />

<ImageView
android:id="@+id/iv_product"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:src="@drawable/vest101"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_name" />

<RatingBar
android:id="@+id/rating_bar"
style="?android:attr/ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:rating="@{product.rating}"
app:layout_constraintBottom_toBottomOf="@+id/tv_price"
app:layout_constraintEnd_toStartOf="@id/tv_num_rating"
app:layout_constraintTop_toBottomOf="@+id/iv_product" />

<ScrollView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_below="@+id/tv_price"
android:layout_margin="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_price"
app:layout_constraintVertical_bias="0">

<TextView
android:id="@+id/tv_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="@{product.description}"
android:textSize="20sp" />

</ScrollView>

<TextView
android:id="@+id/tv_num_rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="50dp"
android:text="@{StringUtils.Companion.getTotalRatings(product.totalRatings)}"
app:layout_constraintBottom_toBottomOf="@id/rating_bar"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/rating_bar" />

<TextView
android:id="@+id/tv_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_name"
android:layout_marginStart="50dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:gravity="center"
android:text="@{StringUtils.Companion.getPrice(product.price)}"
android:textSize="20sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/iv_product" />

<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@{product.name}"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:textSize="30sp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

<data>
<import type="com.databindingexample.model.Product" />
<import type="com.databindingexample.utils.StringUtils" />
<import alias="AndroidView" type="android.view.View" />
<import alias="CustomView" type="com.test.custom.View" />
<import type="java.util.List" />
<variable name="product"type="Product" />
<variable name="view" type="AndroidView" />

</data>

</layout>

Layout Expression Language in Data Binding

The expression language looks a lot like expressions found in managed code. You can use the following operators and keywords in the expression language:

  • Mathematical + - / * %
  • String concatenation +
  • Logical && ||
  • Binary & | ^
  • Unary + - ! ~
  • Shift >> >>> <<
  • Comparison == > < >= <= (Note that < needs to be escaped as &lt;)
  • instanceof
  • Grouping ()
  • Literals — character, String, numeric, null
  • Cast
  • Method calls
  • Field access
  • Array access []
  • Ternary operator ?:
<?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">

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@{product.name != null ?product.description}"
android:text="@{product.name??product.description}" (null check)
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:textSize="30sp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_name"
android:layout_marginStart="50dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:gravity="center"
android:text="@{product.price > 90.0 &amp;&amp; product.price &lt; 150.0 ? 'low' :'high'}"
android:textSize="20sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/iv_product" />
<TextView
android:id="@+id/tv_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="@{stringArray/category[0]}"
android:textSize="20sp" />
</androidx.constraintlayout.widget.ConstraintLayout>
<data>
<import type="com.databindingexample.model.Product" />
<import type="com.databindingexample.utils.StringUtils" />
<import alias="AndroidView" type="android.view.View" />
<import alias="CustomView" type="com.test.custom.View" />
<import type="java.util.List" />
<variable name="product"type="Product" />
<variable name="view" type="AndroidView" />

</data>

</layout>
----------------------string.resource--------------------
<resources>
<string-array name="category">
<item>Sale</item>
<item>Low</item>
</string-array>
</resources>

Data binding best interview question

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

</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.constraintlayout.widget.ConstraintLayout>
<EditText
android:id="@+id/et_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="name"
android:textSize="20sp" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="@{etDescription.text}"
android:textSize="20sp" />
</androidx.constraintlayout.widget.ConstraintLayout>

</layout>

For More Details About data binding Study Part-2

I am really excited about all these new cool things 😍 If you liked the article, clap clap clap 👏👏👏 as many times as you can.

LIKED SO MUCH! Medium allows up to 50 claps.

--

--

Deepak Sikka

Senior Android Developer. Working on technology Like Java,Kotlin, JavaScript.Exploring Block Chain technology in simple words.