If there’s one piece of the core Android framework that every Android dev struggles with, it’s ListView. ListView is incredibly flexible and complex, and you’ll probably find you need it more than once in any decent-sized app. If you haven’t already slammed your keyboard and screamed at ListView before, you probably haven’t been writing Android apps very long. It’s so important, Google even had a whole session about it at their I/O conference in 2010.
ListView is the crucible, the teeth-cutting, the rite of passage for all aspiring Androidians. It’s like Luke seeing Darth Vader in the cave on Dagobah. Once you’ve battled with ListView and emerged from the cave victorious, you’ll know you’re a true Android developer.
This is just one story about ListView.
When I was writing Pokédroid, I came across an interesting problem. The first screen of the app was just a huge list of creatures, but it was too difficult to navigate through. Depending on what game you had, you were only interested in the ones numbered 1-151 (first generation), 152-251 (second gen), 252-386 (third gen), 387-493 (fourth gen), or 494-649 (fifth gen). This meant that the newer (and therefore more interesting) Pokémon were at the bottom, where they were hard to get at. But assuming the National Pokédex numbering, this was just the proper order.
Problem: there were too many goddamn Pokémon.
Too goddamn many.
The solution I came up with was to make the list more navigable by showing “fast scroll” overlays with the names of the various Pokémon generations. Named after the games’ regions, they go “Kanto,” “Johto,” “Hoenn,” etc. That way, the user could immediately know what section of the list they were in, and they could quickly scroll between sections.
Lots of Android apps do a similar thing. The Contacts and Music apps, for instance, show overlays to let you know which part of the alphabet you’re on:
This is made possible by the use of the “fast scroll thumb,” i.e the little grooved square to the right. It allows you to zoom through your list contents and hone in on the item you want. It’s like blasting down the highway and watching the exit signs, versus crawling down a suburban street, inspecting each house number one-by-one. It’s a much better user experience.
So the fast scroll thumb is awesome. And to use it, all you have to do is add fastScrollEnabled=”true” to your ListView’s XML. The only catch? If you want to use it for anything other than alphabetical sorting, your section overlays are going to look like this:
Yup, the overlay has a fixed width, so you can only really use it for single characters. What’s a poor Android developer to do?
As it turns out, the only way to fix this problem is to implement your own version of the Contacts app’s internal FastScrollView and hack it yourself. I wasn’t the first to discover this, but I did post some snippets of the solution to Stack Overflow back when I first implemented it in Pokédroid. Since then, I’ve been getting some questions and clarification requests on the original post, so I decided to go ahead and write a full demo app to show how it works. After all, Pokédroid is and will probably always remain closed-source, but this code at least is probably worth sharing.
The demo app is on GitHub. Since Pokémon is kind of an esoteric subject, I decided to go with the topic of countries and continents instead. In this example, we’ve got a big list of countries, sorted either by continent or by country name. When you use continent-sorting, you can see overlays of the continents:
…and when you sort by the country name, you see alphabetic overlays instead:
Of course, if you wanted to get really fancy, you could vary the width of the overlay based on what kind of sorting you’re using. But it should be clear enough how to do that from the source code. In any case, with Pokédroid, I had a handful of different sorting mechanisms, but the most common ones had rather long titles, so I just kept the width the same for all of them. In the end, it looked like this:
That’s Pokémon sorted by generation, type, and base HP. The possibilities are pretty endless. You can take your ListView and sort it, divide it, slice-n-dice it however you want.
The important thing is that “fast scroll” sections make for a better user experience. ListViews can hold a lot of data, but that doesn’t mean you should let your list get bloated and then leave all the hard scrolling up to the user. I have an app on my phone where the developer uses an unsectioned ListView with over 200 items. Two hundred! It takes almost five seconds just to scroll from top to bottom! That may not sound like much, but in the UI world, five seconds is an eternity.
Just imagine your poor users, holding their phone in one hand and flipping your ListView with the other hand, over and over again, like they’re trying to light a wet match. Then reflect on how much you could improve that experience with some fast scroll sections.
Well, ListView-abusing Android developers (you know who you are): now you have no excuse. The CustomFastScrollView code is public and open-source, so go use it. Get cracking!