Stop repeating yourself and create custom views on Android with Kotlin

Rygel Louv
4 min readApr 12, 2018

--

We all know what custom views are right ? And we know how powerful they can be. But sometimes we might be forgetting why we should create custom views. We can create custom Views to build complicated Views that the Android Framework doesn’t give us like this. However, in engineering school or in software engineering books we learn this precious rule: Don’t repeat yourself. Well, this could also be one of the main reasons why we should create custom views.

Imagine we have to build this screen:

A screen showing the status of action being done in the background

What we basically have is a screen showing status of actions being done probably in the background. We can see that for each action, it is the same pattern or can we say the same View but with 4 different states. And we can describe it like this:

  • DISABLED state: the text has a pale white color and a 3 dots icon on the left
  • LOADING state: the text has a more bright white color and a progress bar on the left
  • DONE state: the text has a more bright color and a check icon on the left
  • FAILED state: the text has a red color and a “x” icon on the left with retry button/icon on the right. This retry icon once clicked will retry the corresponding action.

Now if we have to build this screen what should we do ?

Solution 1, the obvious one: do everything manually

Since you just have 3 elements, you can think about handling everything manually. Which means you will set the color of the text, change the icons, set visibility of the Progressbar all of that according to the results of the actions.

The problem with this approach, you might have guessed it already, is that you will end up with a whole bunch of Views to manage and that can quickly become a big mess and will surely implies a lot of repetition. Especially if we add some other specifications.

Solution 2, the extreme one: create a Recyclerview

You can also think about creating a Recyclerview (or a ListView if you still use it) based on the assumption that it’s mostly the same thing being repeated with just different state.

The real question with this approach is: does the Recyclerview really fit for this kind of view ? We use Recyclerview most of the time to display data but this is just some status to show to the user. The Recyclerview solution will probably work fine even if it could also require a lot of work to achieve this simple goal, but it is not really appropriate for this use case.

Solution 3, the simple one: create a custom view with states

We will call it TextMultiStateView and configure it to work with 4 states:

enum class State{
DISABLED,
LOADING,
DONE,
FAILED
}

Now we need just a single class that will do the job. We can make the class extending from LinearLayout because we can see that the views inside are positioned horizontally one after the other.

You probably notice the merge tag as root node of the layout file. This is because because we don’t want our TextMultiStateView to have a LinearLayout as child view because TextMultiStateView is himself a LinearLayout.

Creating custom views classes in Kotlin might be a bit tricky the first time. On Android, when you create a custom View, like a class extending from View or something else, you need to create the 3 constructors calling super(). But it is not a common use case in Kotlin to have a class with several constructors and most of the time you create a constructor in the class definition with default values. Antonio Leiva has a great article about this specific subject.

You can create the 3 constructors

Or you can let Kotlin handle the constructors by using default values thanks to @JvmOverloads

But this last technique could be dangerous and maybe you should avoid using it. Because it does a lot of assumptions and you may end up with some strange behavior. Sebastian Lobato Genco talks about it clearly here.

We can now build the actual logic of our custom view.

And finally our activity can just declare it like an ordinary view as many times as it wants

And make the configuration in the most simple way.

And we are done.

Now imagine if you chose solution 1, that means you would have been doing the logic of the setState() function 3 times by repeating again again the same logic. And if the view evolves, with more states for example, the complexity behind this evolves as well. And finally, imagine if you have to build this kind of screen several times in your project for different purposes.

As we mentioned above, Custom Views are very powerful tool and this might be a really good reason for considering working with them and a pretty good technique to not repeating yourself and save a lot of coding/debugging time when building your UI.

You can 👏👏 if this was helpful to you and you can share as well. I’m looking forward for your comments where you can tell me opinion about this and what could be other options to solve this.

--

--