Or how and why we have two ways to avoid it
In Android, if you want to change the properties of views from your layout, like changing the text of a
TextView or adding an
onClickListener , you would have to first assign that view’s id to a variable by calling
findViewById . For example, if you only had one TextView with an id of textView, you’d need to write the following Kotlin code:
private lateinit var textView : TextView//in onCreate()
textView = findViewById(R.id.textView)
As you can imagine, this gets pretty verbose for a large number of views. With Kotlin, we have two separate ways to avoid declaring variables and writing
- Kotlin Android Extensions (JetBrains’ approach)
- Data Binding (Google’s approach)
Now let’s look at how you use each of the new approaches:
1. Kotlin Android Extensions
To solve the issue of writing useless code, JetBrains has created the Kotlin Android Extensions which have a number of features, but exist primarily to avoid the need for
findViewById code. Using them is straightforward, you simply need to import
kotlinx.android.synthetic.main.activity_main.* and then you simply reference views by their id from the layout file, for example:
textView.text = "Hello world!"
This is super useful, because it makes all of the code we wrote initially unnecessary. The way it works is basically it calls
findViewById itself and it creates a cache of views it references any time you want to access that view again.
However, there are a number of issues with this, primarily that it’s Kotlin-only and that it still runs the expensive
findViewById operations. For a more in-depth look at the downsides, have a look at this excellent article:
As a result, Google recommends not using them, and instead using:
2. Data Binding
To solve the same issue, as well as add some extra functionality (for example observing data changes), Google has created the Data Binding Library. Using this is a bit more involved than Kotlin Android Extensions, but in theory it allows for more complex manipulation of the data and, most importantly, it avoids
findViewById calls entirely by creating an object that already contains references to all the views that have ids.
To use it, you first need to enable data binding in your app’s
enabled = true
Then, you need to wrap each layout xml file with a
Finally, need to create a variable to reference the object holding all the view ids:
private lateinit var binding: ActivityMainBinding//in onCreate() replace setContentView() with:
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
After that, we can access all views using their ids like so:
binding.textView.text = "Hello world!"//or if you have multiple properties or views using the with keyword
textView.text = "Hello world"
Both approaches offer multiple benefits and expanded functionality so I encourage digging deeper into them if you’re curious, I just wanted to show you how each is used strictly in the context of avoiding writing boilerplate code. If you have any questions you’re welcome to ask them in the comments section below.
Thanks for reading this article. You can connect with me on LinkedIn.
If you liked this article, please hit the clap icon 👏 to show your support.