Multiple row types in RecyclerView

Mateusz Dziubek
AndroidPub
Published in
2 min readNov 17, 2016

Sooner or later every Android developer will face a problem of including few xml row layouts in one RecyclerView like this:

Above list comprises of three independent layouts called row_type_button.xml, row_type_image.xml and row_type_text.xml. How to achieve this result without endless if statements polluting our RecyclerView’s adapter?

The implementation below was inspired by great article I found on SourceMaking. The idea was also supposed to be my attempt to thoroughly understand one of Android classics by Hannes Dorfmann, but I believe it is suitable to be treated as an introduction as well as a standalone solution.

The basic idea is to associate each layout with a separate class and then connect all of those classes via common interface (in our case RowType interface).

Having in mind row_type_button.xml, let’s create a class that initializes OnClickListener:

Having in mind row_type_image.xml, let’s create a class that stores text which later will appear next to an image:

Having in mind row_type_text.xml, let’s create a class that stores two strings — for a header and for a body text:

Now to connect our data stored in classes above with a recyclerView we need to define a custom adapter. Beside standard methods that need to be implemented let’s also make a use of int getItemViewType(int position) and ability of the interface to hold constants (implicit public static final) that will differentiate between data types:

After some extensive usage of instanceof operator and view holders definition we can come up with this implementation of MultipleTypesAdapter:

Right of the bat we can conclude that there’s just too much action (pollution) in this class. Let’s change that!

For starters, view holders can be a subject to factory pattern thus making MultipleTypesAdapter handle one responsibility less:

Furthermore, each class associated with row layout can handle returning proper integer indicating its type and perform view binding itself. For this we need to add two more methods to RowType interface:

Below you can see an exemplary implementation of int getItemViewType() and void onBindViewHolder(RecyclerView.ViewHolder viewHolder) in one of the row type classes (note that there’s no need to have getters now):

As a result of this refactoring we are left with elegant, clean and straightforward code in MultipleTypesAdapter:

Isn’t that just lovely?

--

--

Mateusz Dziubek
AndroidPub

Senior software engineer with acute product sense and business knowledge