The new View Binding feature allows you to write simpler, more concise and safer code to interact with your views.
Since this is built into Android Studio, it requires no dependencies. All we need to do is enable this feature in our module's build.gradle
.
android {
buildFeatures {
viewBinding true
}
}
When this feature is enabled, a binding class is generated for each XML layout within that module. If you want to disable view binding for a particular layout, you can simply annotate the root view of that layout file with tools:viewBindingIgnore="true"
.
Each binding class contains a reference to the root view and to each view with an ID. As an example, let's look at the layout profile_header.xml
below.
<?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="wrap_content">
<ImageView
android:id="@+id/avatar"
android:layout_width="48dp"
android:layout_height="48dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription"
tools:src="@drawable/ic_account_circle_black_24dp" />
<TextView
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:ellipsize="end"
android:lines="1"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
app:layout_constraintBottom_toTopOf="@id/email"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="John Doe" />
<TextView
android:id="@+id/email"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:ellipsize="end"
android:lines="1"
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toBottomOf="@id/name"
tools:text="support@notifica.re" />
</androidx.constraintlayout.widget.ConstraintLayout>
The generated ProfileHeaderBinding
class will contain the following properties:
root
—ConstraintLayout
avatar
—ImageView
name
&email
—TextView
Let's look at some examples!
Using it from an Activity
class SettingsActivity : AppCompatActivity() {
private lateinit var binding: ActivitySettingsBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySettingsBinding.inflate(layoutInflater).also {
setContentView(it.root)
}
binding.name.text = "John Doe"
// ...
}
}
Using it from a Fragment
class SettingsFragment : Fragment() {
private lateinit var binding: FragmentSettingsBinding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
binding = FragmentSettingsBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.name.text = "John Doe"
// ...
}
}
Using it in a RecyclerView.ViewHolder
The generated binding class also provides a static bind
method to handle an existing view instead of inflating it.
class ProfileViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val binding = ProfileHeaderBinding.bind(itemView)
fun bind() {
binding.name.text = "John Doe"
// ...
}
}
Advantages of view binding
There's two major advantages of view binding when compared to the traditional findViewById
.
- Type safety. The properties of the generated class have their types matching the ones if the XMl layout. This prevents class cast exceptions during runtime, failing instead at build time.
- Null safety. If a certain view is not present in all variations of a given layout it will be marked as nullable. It will force you to handle it in your code, preventing some more exceptions during runtime.
Wrapping it up
For more information, you can check the official documentation. Additionally, Google provides an open-source sample.
If you liked this article or have something to add, we are available, as always, via our Support Channel.