Android Data Binding Library

Andrea
3 min readJul 11, 2021

--

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. It is basically removed the need of using findViewById<>() and we put data on the xml layout fiile itself.

Preparation :
Enable the data binding feature on your build.gradle

android {
...
dataBinding {
enabled true
}
}

Now we can convert the layout to a Data Binding layout.
1. Wrap your layout with a <layout> tag
2. Add layout variables (optional)
3. Add layout expressions (optional)

Now our layout should 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>

</data>

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

We can bind our data in data column. Let us try to bind simple String data to be display in TextView :

<?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="stringData"
type="String" />

</data>

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

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{stringData}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

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

Now that the stringData variable has been bind to our layout, we can set the stringData content programmatically.

class MainActivity : AppCompatActivity() {
private lateinit var binding : ActivityMainBinding

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

binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)


//set stringData programmatically
binding.stringData = "This data set programmatically"
}
}

Bind viewmodel to handle userEvents and actions also possible. As shown on bellow snippet, we can bind viewModel to layout, and also bind action from its viewModel.

...
<data>
<variable
name="mainVM"
type= "com.andreasgift.medium_databinding.MainViewModel"/>

</data>

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

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{mainVM.stringData}"
android:onClick="@{() -> mainVM.actionVM()}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

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

This means we can observe LiveData from Activity and layout will automatically display it.

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private lateinit var binding : ActivityMainBinding
private val viewModel by viewModels<MainViewModel>()

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

binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)


viewModel.stringData.observe(this, Observer {
binding.mainVM = viewModel

})

}
}

We can also custom field data on our layout with Binding Adapter. For example, lets create custom field data that will display whether the TextView will be Visible or Gone

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{mainVM.stringData}"
android:onClick="@{() -> mainVM.actionVM()}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:visibleOrGone = "@{mainVM.visibleOrGone()}"/>

Next, we need to create the BindingAdapter that will tell our layout what should we do with the view after we get this data. We can create new class called MyBindingAdapter :

object MyBindingAdapter {

@BindingAdapter("app:visibleOrGone")
@JvmStatic
fun setVisibility(view: View, data: Boolean) {
if (data) {
view.visibility = View.VISIBLE
} else {
view.visibility = View.GONE
}
}
}

The last step, dont forget to import our new BindingAdapter to its layout.

<data>
<variable
name="mainVM"
type= "com.andreasgift.medium_databinding.MainViewModel" />

<import type="com.andreasgift.medium_databinding.MyBindingAdapter"/>
</data>

Last cheat sheet, on how to display data binding from Fragment. We need to create binding getter.

class MainFragment : Fragment() {
private var _binding: FragmentMainBinding? = null
private val binding get() = _binding!!


override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentMainBinding.inflate(layoutInflater, container, false)
val view = binding.root

return view
}
}

That is all for Android Data Binding. I hope it will help for other developer to understand it deeper.

--

--

Andrea
Andrea

No responses yet