View Binding

View binding is a feature that allows you to more easily write code that interacts with views. Once view binding is enabled in a module, it generates a binding class for each XML layout file present in that module. An instance of a binding class contains direct references to all views that have an ID in the corresponding layout.

In most cases, view binding replaces findViewById.

Setup instructions

View binding is enabled on a module by module basis. To enable view binding in a module, add the viewBinding element to its build.gradle file, as shown in the following example:

android {
    ...
    viewBinding {
        enabled = true
    }
}

If you want a layout file to be ignored while generating binding classes, add the tools:viewBindingIgnore="true" attribute to the root view of that layout file:

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

Usage

If view binding is enabled for a module, a binding class is generated for each XML layout file it contains. Each binding class contains references to the root view and all views that have an ID. The name of the binding class is generated by converting the name of the XML file to camel case and adding the word "Binding" to the end.

For example, given a layout file called result_profile.xml:

<LinearLayout ... >
    <TextView android:id="@+id/name" />
    <ImageView android:cropToPadding="true" />
    <Button android:id="@+id/button"
        android:background="@drawable/rounded_button" />
</LinearLayout>

The generated binding class will be called ResultProfileBinding. This class has two fields: a TextView called name and a Button called button. The ImageView in the layout has no ID, so there is no reference to it in the binding class.

Every binding class also includes a getRoot() method, providing a direct reference for the root view of the corresponding layout file. In this example, the getRoot() method in the ResultProfileBinding class returns the LinearLayout root view.

To get an instance of a generated binding class, you call its static inflate() method. Typically, you will also call setContentView(), passing the root view of the class as a parameter in order to make it the active view on the screen. In this example, you can call ResultProfileBinding.inflate() in an activity:

Kotlin

private lateinit var binding: ResultProfileBinding

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

Java

private ResultProfileBinding binding;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = ResultProfileBinding.inflate(layoutInflater);
    setContentView(binding.root);
}

The instance of the binding class can now be used to reference any of the views:

Kotlin

binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }

Java

binding.name.text = viewModel.name;
binding.button.setOnClickListener(new View.OnClickListener() {
    viewModel.userClicked()
});

Differences from findViewById

View binding has important advantages over using findViewById:

  • Null safety: Since view binding creates direct references to views, there's no risk of a null pointer exception due to an invalid view ID. Additionally, when a view is only present in some configurations of a layout, the field containing its reference in the binding class is marked with @Nullable.
  • Type safety: The fields in each binding class have types matching the views they reference in the XML file. This means that there's no risk of a class cast exception.

These differences mean that incompatibilities between your layout and your code will result in your build failing at compile time rather than at runtime.

Differences from the data binding library

View binding and the data binding library both generate binding classes that you can use to reference views directly. However, there are notable differences:

  • The data binding library processes only data binding layouts created using the <layout> tag.
  • View binding doesn't support layout variables or layout expressions, so it can't be used to bind layouts with data in XML.