A simple pain point I always seemed to encounter when developing for Android is dealing with multiple items types in a ListView
or a GridView
.
Luckily, RecyclerView
has some pretty neat built in support for this feature, and I've used it successfully with collections containing >10 item types.
Adding that kind of complexity can lead to lots of ugly code in your adapter, and trying to keep that clean will help in maintainability and reduce possible bugs.
Let's build a quick app that shows various fruits and veggies with specific styling for their type.
First off, lets start with the crux of the implementation: the Adapter's item model.
1 |
|
Using this object, we can wrap the item's model and have it specify it's item type for the adapter.
Next, let's use it in the adapter:
1 |
|
By exposing a simple API for each item type, the adapter can control how and where each item is added into it's backing collection.
ViewHolders
Since we have different items, it makes sense to have different item ViewHolder
objects and layouts.
1 |
|
1 |
|
The key in the ViewHolder
object is that it exposes static create
and bind
method calls.
The create
method is just a static factory method, a common practice in Java.
The bind
method, however, allows use to abstract all ViewHolder
binding logic into the object itself, rather than polluting the adapter's #onBindViewHolder
method.
Adapter
Now that we've setup the wrapper object and the viewholder logic, lets take a look at what the adapter has to do to button all this up.
First off, make sure you override the RecyclerView.Adapter#getItemViewType
method.
This method lets the adapter know to expect multiple view types and not attempt to use a recycled ViewHolder
of the wrong type.
1 |
|
Finally, the adapter needs to actually create and bind the view holders:
1 |
|
Finale
Now you get to use it:
1 | String[] fruits = getResources().getStringArray(R.array.fruits); |
What it ends up looking like:
From here, adding new item types is quite simple:
- Add a
ViewType
to theFruitVegItem
- Create your
ViewHolder
and layout - Hook it all up in the adapter
Encore
When you start using viewtypes like this, you can create some pretty fun, complicated layouts easily via the GridLayoutManager
For example:
1 | gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { |
You can view the full code (plus click listener implementations) on github