data-binding
fragments
android development
mobile app development
programming tutorial

How to use data-binding with Fragment

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Android data binding lets a layout talk directly to a ViewModel or other observable data source, which removes a lot of view lookup boilerplate. In a Fragment, the important part is not just creating the binding, but also tying it to the fragment view lifecycle so you do not leak references after onDestroyView().

Enable Data Binding and Create a Layout

First, enable data binding in your module build.gradle file:

gradle
1android {
2    buildFeatures {
3        dataBinding = true
4    }
5}

Then wrap the fragment layout in a layout root and declare the variables you want to bind:

xml
1<layout xmlns:android="http://schemas.android.com/apk/res/android">
2
3    <data>
4        <variable
5            name="viewModel"
6            type="com.example.app.UserViewModel" />
7    </data>
8
9    <LinearLayout
10        android:layout_width="match_parent"
11        android:layout_height="match_parent"
12        android:orientation="vertical">
13
14        <TextView
15            android:layout_width="wrap_content"
16            android:layout_height="wrap_content"
17            android:text="@{viewModel.userName}" />
18    </LinearLayout>
19</layout>

When the layout is compiled, Android generates a binding class such as FragmentUserBinding.

Inflate the Binding in the Fragment

Inside the fragment, inflate the generated binding class instead of using findViewById:

kotlin
1class UserFragment : Fragment() {
2
3    private var _binding: FragmentUserBinding? = null
4    private val binding get() = _binding!!
5
6    private val viewModel: UserViewModel by viewModels()
7
8    override fun onCreateView(
9        inflater: LayoutInflater,
10        container: ViewGroup?,
11        savedInstanceState: Bundle?
12    ): View {
13        _binding = FragmentUserBinding.inflate(inflater, container, false)
14        binding.viewModel = viewModel
15        binding.lifecycleOwner = viewLifecycleOwner
16        return binding.root
17    }
18
19    override fun onDestroyView() {
20        super.onDestroyView()
21        _binding = null
22    }
23}

Two lines matter most:

  • 'binding.viewModel = viewModel connects the layout variable to the fragment data source'
  • 'binding.lifecycleOwner = viewLifecycleOwner allows LiveData updates to observe the fragment view lifecycle correctly'

Without the lifecycle owner, LiveData expressions in XML may not update as expected.

Bind LiveData from a ViewModel

Data binding becomes most useful when paired with a ViewModel:

kotlin
1class UserViewModel : ViewModel() {
2    private val _userName = MutableLiveData("Alice")
3    val userName: LiveData<String> = _userName
4}

Because the layout binds android:text to viewModel.userName, any change to that LiveData updates the TextView automatically while the fragment view is active.

This works well with MVVM because:

  • UI logic stays mostly in XML and the fragment
  • business state stays in the ViewModel
  • view lookup code is reduced

If you need click handling, you can also expose methods on the ViewModel or fragment and bind them in XML, but keep expressions simple so the layout does not become hard to debug.

Know the Difference Between Fragment and View Lifecycle

Fragments outlive their views. That is the reason the nullable _binding pattern exists. If you keep a strong binding reference after onDestroyView(), the old view tree can leak.

That is why this cleanup is not optional:

kotlin
1override fun onDestroyView() {
2    super.onDestroyView()
3    _binding = null
4}

This is the most common correctness issue when developers first use data binding with fragments.

Common Pitfalls

The biggest mistake is setting binding.lifecycleOwner = this instead of viewLifecycleOwner. The fragment lifecycle and the fragment view lifecycle are not the same, and using the wrong owner can keep observers active longer than intended.

Another issue is holding onto binding after the view is destroyed. In fragments, always null the backing field in onDestroyView().

Some developers also move too much logic into XML expressions. Simple bindings are great, but large conditional expressions or formatting rules belong in the ViewModel or a binding adapter, not buried in the layout.

Finally, make sure the XML root is actually layout. If that wrapper is missing, Android will not generate the binding class you expect.

Summary

  • Enable data binding in Gradle and use a layout root in the fragment XML.
  • Inflate the generated binding class inside onCreateView().
  • Set both the bound variables and binding.lifecycleOwner = viewLifecycleOwner.
  • Clear the binding in onDestroyView() to avoid leaks.
  • Keep XML bindings simple and let the ViewModel own application state.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.