Getting started with Android ViewBinding
Learn how to get started using the new feature for faster and safe view bindings on your Android projects
View Binding on Android: a brief story
The Era of findViewById()
On early ages of Android, developers were used to inflate views by calling findViewById()
. However, this task could become really cumbersome in an instant. For instance, declaring 3 views it would require at least 3 additional lines just for the sake of views inflation. Now imagine a more complex UI on real projects. Often, we needed to add a bunch of boilerplate code like the following one (along with Java's verbosity):
The Rise of View Binding Libraries
In order to improve our productivity and get rid of repeated inflation tasks, community have been developing great libraries, such as the well known ButterKnife (thanks, Jake👏) which among other cool features, allowed us to bind views using annotations.
Kotlin Android Extensions Synthetic Properties
As Kotlin popularity grows on Android community, we claimed for a more concise and cleaner way to bind views. A suitable approach came with Kotlin Android Extensions plugin, via synthetic properties which generates a bunch of properties to allow accessing views directly by referencing layout id from code. Although this approach brings a cleaner development, it has some caveats:
- It’s really tricky to reference same view ids from different layouts in a single class. A very common and useful workaround is to add some aliases and update your code to use them in favour of the real view id.
- It generates a bunch of code whenever the layout changes in order to synthesise all properties
- It’s no longer a recommended practice from Google on Android development. There’s actually a buzz around all this discussion
Albeit the above approaches have helped us on getting rid of findViewById()
, all its productivity comes with a cost. They rely on annotation processing under the hood, thus adding overhead that might affect the build time.
Introducing ViewBinding: a faster and safe way to bind views
During the "What’s New in Android" session presented on I/O 2019, Google has announced a new faster and safe fashion to bind views, a tool called ViewBinding. As the time of this article writing, it's an experimental tool available as of Android Studio 3.6 Preview Canary 11, that you can already start playing with.
Setup
- Download Android Studio 3.6 Preview Canary 11
- For those who want to first check the overall code, I've created a toy project that displays basically 3 views: two EditTexts and one Button that is enabled when both fields are not empty and shows a Toast with field contents concatenated whenever it's clicked. You can download it from repo link below:
But if you want to start from scratch, create a sample Android Project and update activity_main.xml
with the following XML layout content:
4. Enable ViewBinding by adding viewBinding
task in your build.gradle (app module) file
Note: If you already have dataBinding enabled on your project, you don’t need to add
viewBinding
support.
4. Sync your project and wait to finish building.
How ViewBinding works under the hood?
ViewBinding engine generates a 1:1 relationship between the binding class and the layout file. Regarding the sample project, a class ActivityMainBinding
was "automagically" generated according to the activity_main.xml
, containing references to nameField
, surnameField
and bindUserButton
views that have id defined.
Besides, a getRoot()
method is also generated to retrieve the root view for the underlying layout, the ConstraintLayout
in our case. The code below shows MainActivity
after updating it to call ActivityMainBinding
.
We pretty much need to switch this code:
To this one:
Oh…wait, no more need to call R class? Yay! 🎉
ActivityMainBinding.inflate(LayoutInflater)
inflates the whole layout hierarchy to access views. The ViewBinding mechanism abstract us about the real layout file access through the old R class. Instead, we pass binding.root
as parameter to setContentView()
.
And after binding all views from ActivityMainBinding
we get this result code:
Thanks to Kotlin conciseness nature, we can improve this code and avoid repeated call from binding
by calling either with
or apply
functions:
What makes ViewBinding a so promising feature?
The new ViewBinding feature has some advantages compared to approaches aforementioned that makes it so promising to turn into a de-facto standard for view binding:
- null-safety: The binding class is comprised by all view references that have ids defined in layout. And if the View can be nullable for a specific context (i.e. if a view is missing in some layout configuration), the view reference is generated with a
@Nullable
annotation for that view, thus avoiding catchingNullPointerException
. - type-safety: All view binding methods are generated matching the same type as defined in XML, so there’s no need to typecast, let alone get a smart cast exception. If for some reason your layout and code doesn’t match, the build will fail at compile time instead at runtime.
ViewBinding vs. DataBinding
The main difference between the DataBinding approach is that we do not need to add <layout>
tag via XML to enable data binding process. However, as the tool name suggests, the ViewBinding is supposed to bind only views but not data.
Wrapping up
We’ve just scratched the surface about the overall potential of ViewBinding feature. Looking forward to seeing community trying it out and improving it prior to AS 3.6 release. Some cool things that I'll try to explore on upcoming posts:
- ViewBinding on Custom Views
- ViewBinding on ViewHolders
- ViewBinding on UI Espresso tests
Links
If you enjoyed this post, please don’t hesitate to give 👏 to help spread it across community.
Happy code! :)