ViewBinder for Android in Kotlin

Various projects are starting to use Kotlin as their default language as more people are finding out about it and loving it — and it is still beta (Beta 4 as the time of writing). This just reinforces the good job JetBrains is doing. But I didn’t write this to sell you Kotlin, I wrote this to show how we improved our code with niceties from this language.

I wanted to write a bit about my personal experience using Kotlin in Android — describing how some things change, others become easier and some harder. Tell you it’s not so different from Java — until it is. But then I realized writing something like that would add little value. Here are the most notable articles from 2015 about Kotlin.

MVP (Model View Presenter)

I am going to use Model View Presenter as the architectural style for this (hypothetical) app. MVP is a good pattern because it splits the responsibility of each part of your app, decoupling how the data is retrieved from how it is shown to the user. The View will be responsible for displaying the data; the Presenter for how to get the data and pass it to the View; and the Model for how the data is modeled, retrieved and stored.

I’ll further improve this by creating a View model. By making a transformation from my data model to my View model, the View model doesn’t need to know anything about how my data is structured. For example, my View model needs to show the company name of my user. There is a Company model inside my User model. My View doesn’t have to care about this nesting, only about the company name. When creating my View model I can extract the company name from my data model complex structure and add only its name to the View. The View and the data are nicely decoupled.

Delegated Properties

Kotlin’s Delegated Properties are really cool. Official documentation explains better than I could (another great thing about Kotlin), but essentially you can wire a class to execute some code when calling get() or set() of a property. A famous delegate within Kotlin is Lazy property. The first call to get() executes the lambda — a function that you pass to lazy() — and returns this value to the caller. After that the result is stored and subsequent calls return it.

ViewBinder

After this little background we can talk about what we did to improve our code. We wanted to have something that could reflect the changes of our ViewModel in the Activity automatically, without calling a lot of methods or creating listeners. This was inspired by DataBinding by Google. Unfortunately we couldn't use it because it uses an older version of Kotlin — we can't use a library that compiles against an older version than the one we are using.

So this is where Delegated Properties came in. We did something similar to ObservableProperty: when set() is called on the property, a lambda — that you passed to ViewBinder — is executed. By using this we could have all the code that modifies our View in one place. Or just a few places, as we can have various properties with this Delegate.

Example of usage

Let’s imagine that we have a screen in our app that shows user information. In this example, we have to:

  • Have our Presenter make an API request to get user information;
  • With our API response, we create a ViewModel for our View and set on it;
  • As soon as the ViewModel changes, our ViewBinder will be executed, changing everything that is needed — on this case, filling our TextViews.

It’s that easy! When the API returns, the Presenter creates an AccountViewModel and calls set() on the AccountView. Automatically, our ViewBinder kicks in the lambda with the new value and changes our TextViews with the new informations.

As I said we didn’t need to create the ViewBinder class. The observable could do that for us. That said, it’s refreshing to do something by yourself once and awhile. We even managed to do something as simple as Kotlin team did, with simply one method on the constructor.

Conclusion

These are some of the little things that we can do with Kotlin that make me happy to work with it. We didn’t even need to use Extensions, that give us developers much more power (and greater responsibility).

Bonus

Another fantastic method that I found on Kotlin is apply(). It saves you some lines of code and headache. When you invoke it, you need to pass a lambda. Inside this lambda you can refer to your caller object (and its properties/methods) without calling it, because it is executed inside its scope. It then returns this object. It’s easier to understand with an example.

So, in this example I have a method that can receive a null Toolbar (because not all Activities have Toolbars, right?). If my Toolbar is not null I can set() the title, create a listener and doSomething(). The way Kotlin works we would need to check every time if the Toolbar is really null. But with apply() we just need to check once, in a beautiful way.

Without using apply():

override fun setupToolbar(toolbar: Toolbar?) {
    toolbar?.titleResource = R.string.title_account_activity
    toolbar?.setNavigationOnClickListener { onBackPressed() }
    if (toolbar != null) doSomething()
}

Using apply() (just 1 null check):

override fun setupToolbar(toolbar: Toolbar?) {
    toolbar?.apply {
        titleResource = R.string.title_account_activity
        setNavigationOnClickListener { onBackPressed() }
        doSomething()
    }
}
Show your support

Clapping shows how much you appreciated Tsuharesu’s story.