Kotlin’s sealed class ordinals with Recyclerview adapter

Let’s perfect RecyclerView’s adapter item types with sealed classes.

Dionysis Lorentzos
Dionysis’ desk
3 min readMay 3, 2020

--

Nutech’s main list has 7 view holder types

Here’s a small “code bliss” pattern which we use in Nutech — Android jobs app’s list adapters.

With this code pattern, we believe we finally have one, clean way to write adapters.

Let’s start.

By now, we assume (and hope) that you already use sealed classes for both Adapters’ items and view holders. So your average case should look pretty much like this:

And in this scenario, because we have more than one item type, we have to define the item type in the adapter. The type must be defined with an Int. So we usually do something like:

Let’s change the above and automate the above types (0 and 1 above) with ordinals! As if a sealed class was an enum. To do that, we need to:

  1. Return the type in the getItemViewType
  2. Match the type of the onCreateViewHolder

The trick here? Make our sealed class items have ordinals. Like enums do.

Calculate the type of the instance

The first step to automate this type’s calculation is to calculate the subclass’s ordinal

That way you can now get the type of any item in one function in a generic way:

So i.e. a HeaderViewHolder item will return 0 and JobViewHolder item will return 1.

Calculate the type of the class, statically

The second (and final step) is that we wish to use the .ordinal() statically like:

Thus, let's extend the .ordinal() function for the static usage:

🔥 Issue, this will not work for data classes, only for objects. So in our example, JobItem.ordinal() cannot be called because JobItem is a data class.

The solution? ✅ An empty companion object in each data class:

Final result

Getting and resolving the view holder’s type is now just a readability bliss 💯

Gist source

⚠️ Note: The code ordinal() will work only with 1st level sealed classes. If you need something more sophisticated, make sure to adjust that method accordingly.

⚠️Note 2: Like many features using reflection, when using R8’s or Proguard’s obfuscation, you can encounter runtime crashes. You need to make sure both the classes and the companion objects are available during runtime. One way to do it is with the @Keep annotation.

Thank you for reading!

Want to learn more about me? I’m Dionysis, an Android dev at ShareNow + Founder of Nutech, a jobs app only for Android developers.

If you are an Android developer, you will most likely be interested in Nutech app.

--

--

Dionysis Lorentzos
Dionysis’ desk

Dionysis is an Android dev ShareNow + Founder of Nutech, a jobs app only for Android developers. He is passionate about auto industry innovation & space