A multi-column list

The requirement

Imagine that you’re developing an app and the designer hands you this sketch of the new UI.

sketch

This is a two-column list where items have varying height and does not align with each other. In this case we know that the number of items is large so there is no possibility of using a ScrollView to solve it. From a design point of view this is pretty straight forward but it turns out that there’s no standard view that will be able to solve it.

How would you solve this?

A work-around perhaps?

One option is to use two ListViews next to each other. This might solve the layout part but it is far from trivial to keep those to list synchronized (especially since the two lists probably wouldn’t have the same height). Also, you would probably have very complicated (and bug-prone) adapter code that handles the two lists and what item ends up in what list.

Another thing to think about is that the above solution only solves it for two columns. And your designer may very well give you a new sketch a week later and say that for tablet devices it looks better with three columns instead of two. And now the separate ListView solution seems even more impossible to implement.

Or maybe a custom list view?

In my view, the best way to implement a multi-column list like the one in the sketch is to implement a custom ListView that can handle columns in the way we need. Of course, there’s a drawback with everything and the drawback with building a custom list view is that you get almost nothing for free. You of course need to implement the multi-column layout. But you also need to handle scrolling, flinging, clicking items and updating pressed state on them and so on.

This is also a quite complex task that will take some time to implement, but it wouldn’t be a work-around. The code for the list view would be complex but only because it’s a list view and not really because it has columns. And the application code (or the adapter) wouldn’t even know that we have columns, it’s just a different view. Also, it’s reusable.

I’ve seen quite a few apps where the developers have implemented the work-around solution instead of the (in my opinion) better solution of implementing a custom view. I think both developers, applications and users would be better of if there were less work-arounds and more developers doing custom views where it’s called for.

Or maybe use an existing component?

As it happens, I just implemented a component like this so a third option would be to use the ColumnListView that I made. It has support for the basic things, but definitely not everything the regular ListView has support for (which is way more than most application has use for). Also, since I had to implement the scrolling in the list myself, I’ve implemented a more boncy iOS-like overscroll which I prefer.

device_screenshot

You can find it on github here.

(It’s an Android Studio and Gradle project and in my experience there can be quite a lot of problems when importing them. For reference I’ve used version 0.4.0 of Android Studio and Gradle 1.10.)

Feel free to use it if you have the requirement of a multi column list with items of varying heights. Or just set the number of columns to one and then you have a basic regular list with iOS style overscrolling if you like that. You can control the amount of columns, whether it should allow overscroll or not and the scroll/fling dynamics using xml attributes.

5 Comments

  1. musa

    Thanks for this… i have a feeling i’m gonna need something like this soon

  2. jk

    Thanks heaps!

  3. Rennan

    That is very nice and work well
    but I’m trying to implement a search implementing Filterable in MyAdapter
    FATAL EXCEPTION: main
    java.lang.IndexOutOfBoundsException: Invalid index 4, size is 3

    the problem is because the method getView the position comes with the same initial size getCount being getCount () {

    return itensFiltered.size ();
    }

    returning the right size of the filtered items

    You have any idea how can I do?

Leave a Reply