Exploring Android View Binding in Depth
Using ViewBinding with <include>, <merge>, adapters, fragments, and activities
Google introduced view binding in the What’s new in Android session at Google I/O 2019.
There is a brief talk about view binding in What’s New in Architecture Components, which compares view binding with existing solutions and further talks about why view binding is better than existing solutions like data binding or Kotlin synthetics.
For me, Kotlin synthetics was working fine but all the IDs reside in a global namespace so if you are using an ID with the same name and if you import the ID from the wrong layout, you’re going to get a crash because the ID is not part of the current layout and there is no way to know this in advance unless you run your app and go to that layout.
The following article has a nice overview of problems with Kotlin synthetics.
View binding will be available in Android studio’s 3.6 stable version but if you want to try it, you need to download Android Studio 3.6 RC 3.
The main advantage of view binding is that all the binding classes are generated by the Gradle plugin so it doesn’t have an effect on build time and it has compile-time safety (which we will see in our examples).
Let’s start by enabling view binding. We need to add the following in our module’s
enabled = true
Note: View binding is enabled on a module-by-module basis so you need to add the above code in every
build.gradle file if you have a multi-module project setup.
If you want to disable the view binding specific layout then you need to add
tools:viewBindingIgnore=”true” to the root view of the layout file.
After enabling, we can start using it right away and all the binding classes are generated by default when you finish syncing your
It generates a binding class by converting the XML layout file name to the camel case and adding
Binding at the end of it. For example, if your layout file is named
activity_splash then it will generate the binding class as
How Do I Use It?
We have our layout file named
activity_splash and in it, we have a
TextView with ID
tvVersionName so when using view binding, all we have to do it get the reference of the binding class, like:
val binding: ActivitySplashBinding = ActivitySplashBinding.inflate(layoutInflater)
And use its
getRoot() in the
setContentView() method which returns the root layout of our layout. Views will be accessible from the binding class object we created and we can use it right after creating the object like this:
binding.tvVersionName.text = getString(R.string.version)
Here, the binding class knows that
tvVersionName is a
TextView so we don't have to worry about typecasting.
Using view binding is a little different in fragments. We need to pass
ViewGroup, and an
attachToRoot boolean variable which we get by overriding
We also need to return the view which we can do by returning the root view by calling
binding.root. You also noticed that we are using two different variables and the
_binding variable is set to null in
That’s because the fragment’s lifecycle is different from the activity’s and the fragment can outlive their views so we can get memory leaks if we don’t set it to null.
The other variable is there to avoid a null check with
!! by making one variable nullable and the other one non-null.
In RecyclerView adapter
row_payment.xml is our item layout file for the
RecyclerView’s row and that’s why the
RowPaymentBinding class gets generated.
Now, all we need to do is call the
inflate() method and pass the required parameters that are available inside
onCreateViewHolder() and pass the generated binding class object in the primary constructor of our
PaymentHolder class and pass the
itemBinding.root to the
RecyclerView.ViewHolder() constructor. That’s it.
Dealing With the <include>d Layout
View binding can be used with the
<include> layout tag. There are usually two kinds of
<include> tags included in layouts, with or without
We need to assign
<include> an ID and then use that ID to access the view inside the included layout. Let’s see an example of that.
In the above code, we included a common toolbar in our layout file and
<include> has an
android:id=“@+id/appbar” ID which we will use to access the toolbar from
app_bar.xml and set it as our support action bar.
Sometimes we have a layout with the
<merge> tag which helps to eliminate redundant view groups in your view hierarchy when including one layout within another.
And this layout is included as usual inside our layout file.
If we try to give this
<include> an ID, the view binding won’t generate the ID in the binding class so we can’t access the view as we did in the case of the normal include.
In this case, we have
PlaceholderBinding which is an auto-generated class for
<merge> layout file). We have to call its
bind() method and pass the root view of the layout in which we included it.
Then, we can access views inside our
placeholder.xml from our class like
Thanks for reading. I’d love to hear from you in the comments.