Joe Birch

Exploring View Binding on Android

When it comes to manipulating our user interfaces within Android applications, there are a couple of approaches that we can take. In these cases, we need to obtain a reference these views in-order to manipulate them in some way. For this, we’ll either use findViewById(), followed by casting the view to the corresponding type. Or if we’re using kotlin, then we’ll use the kotlin android extensions to perform synthetic access to the views from our layout files. Whilst these two are perfectly fine approaches to take, they do come with some possible pitfalls:

To alleviate the above issues, View Binding introduces us to Binding classes that will bind the views defined in our XML layout to a generated class which can be used within our activities / fragments. Using this generated class we can then access the views available from the binding, giving us some of the following advantages. Note: It’s important to be aware that this View Binding is different from Data Binding – we do not use ViewBinding to bind layouts with data in XML.

With the above in mind, we can see that View Binding provides us with an approach that makes the accessing of views less error prone – allowing us to reduce the chances of crashes occuring for our users.


When it comes to View Binding, there are a couple of concepts which come together in-order to provide this functionality. To begin with we’ll be working the same within our XML layouts, the main difference is that we need to declare a class inside of our activity that will create the binding that create the relationship between

Note: You’ll need to be using at least Android Studio 3.6 Canary 11 to use View Binding

To get started with adding View Binding to our android application, we need to go ahead and add the following to the corresponding build.gradle file:

android {
    …
    viewBinding {
        enabled = true
    }
}

View Binding is module specific, so you will need to add this to each module that you wish to provide view binding for. If you are going to be using this in every module, then you can place this inside of the project build.gradle file in a manner that allows you to reuse it throughout your project.

When it comes to our XML files, we don’t actually need to do anything differently to be able to access views from the generated binding classes – most of the changes will come from within the classes that are accessing those bindings. Let’s say we have a layout file for an activity called add_profile.xml, which looks a little something like this:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
        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"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <TextView
            android:id="@+id/text_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toTopOf=
                "@+id/button_authenticate"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    <Button
            android:id="@+id/button_add_profile"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="16dp"
            android:text="@string/label_authenticate"
            android:layout_marginBottom="24dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

We’re going to want to access these views from within our activity so that we can assign the corresponding content to them. To do this we’re going to need to declare a binding class for that layout file. When we want to declare this binding class we need to adhere to the naming convention defined by the View Binding API – so for example, for add_profile.xml this will look like so:

private lateinit var binding: AddProfileBinding

To begin with, the API will take the name of our layout file, remove any underscores and then sentance-case the words that were seperated by these underscores. Finally, you can see here that the word Binding has been added to end of our file name – this is required and will be added for every view binding class that is generated. Now that we have this binding class declared, we need to assign a reference to it. For this, we’re going to use the LayoutInflator reference within our activity and call the static inflate() method on our Binding class. Doing so will inflate our layout into our binding class so that our bound views are accessible for use.

@Override
 fun onCreate(savedInstanceState: Bundle) {
     super.onCreate(savedInstanceState)
     binding = AddProfileBinding.inflate(layoutInflater)
     setContentView(binding.root)
 }

You’ll also notice here that we are setting the content view of our screen to this root property from the binding. Every binding that is created has a root – this root represents the root component within the layout file that we inflated into the binding class. This is a convenient way for us to be able to finalise the display of our screen.

At this point we have our binding class and can finally use it to setup our screen. Looking at the previous add_profile.xml file from above, you may recall seeing a textview and button. We’ll now access these from our binding class and configure them for display:

binding.textTitle.text = getString(R.string.some_string)
binding.buttonAddProfile.setOnClickListener {
    // do something
}

You can see here that we’re accessing the components that are defined within our layout file (with the underscores removed and camelcase applied). Regardless of the views in our XML, the way we access them here will apply for all view types. Here you can see no casting in place – when we access the textTitle field, that is referenced as a TextView as that’s what the binding class has allocated it. The same applies for the addProfileButton – without any casting in place we avoid incorrect castings being made, as well resulting in code that is more readable. As well as this, we get the advantages mentioned previously when it comes to view binding. Another point being nullable views, allowing us to handle these cases appropriately:

binding.buttonAddProfile?.setOnClickListener {
    // do something
}

In some cases there may be components that you do not wish to create bindings for – maybe you do not want them available for manipulation from with the corresponding binding class. Here, you can make use of the viewBindingIgnore attribute from within our XML layout to exclude this view from being added to the generated binding class.

<TextView
    ...
    tools:viewBindingIgnore="true" />

Whilst this has been a quick dive into View Binding on Android, I hope that it’s been enough to demonstrate the advantages that this approach to view manipulation gives us in our applications. Whether it’s type safety, null safety or an overall cleaner approach to view references in our code, View Binding offers functionality that all applications will be able to take advantage of.

Have you tried View Binding yet? Or have any thoughts / questions on the content outlined here? If so, I would love to hear from you!