TLDR:
Usually, in a RecyclerView
implementation, between the Adapter
and the LayoutManager
, there is a one-view-per-item ratio. We are hoping to find a way to create multiple views per item.
Note: Please don't confuse this with being able to create different view types based on adapter position. For simplicity assume there is only one view type.
Full Question:
For our project, we need to create a multi-column list. A multi-column list is visually identical to a grid, but has one noticeable difference; in a grid (like that created with GridLayoutAdapter
), one 'cell' (i.e. View
/ViewHolder
) represents one item. In a multi-column list, one row represents one item. The cells that make up that row each display different properties of that same, single item.
As an example, say I have a list of ten Foo objects, and Foo defines five properties which we want to display in columns. From the perspective of our dataset, there are ten items. From the perspective of the LayoutManager
however, there are fifty (ten items (the rows) times five cells (the columns) per row/item.)
The approach I'm leaning to is to create a co-dependent RecyclerView.Adapter
/ RecyclerView.LayoutManager
pair.
First, in my adapter subclass, in addition to creating a property to hold my data items, I also added a 'columnCount' property. Then in the getItemCount()
override, rather than returning the number of items like one would normally do, I instead return the number of items multiplied by the columnCount, like so:
private List<Object> items;
public List<Object> getItems(){
return items;
}
public void setItems(List<Object> items){
this.items = items;
notifyDataSetChanged();
}
private int columnCount = 1;
public int getColumnCount(){
return columnCount;
}
public void setColumnCount(int columnCount){
this.columnCount = Math.max(columnCount, 1);
notifyDataSetChanged();
}
@Override public final int getItemCount(){
return getItems().size() * getColumnCount();
}
Next in my RecyclerView.LayoutManager
subclass, I configure it to grab the passed-in adapter, and if I can cast it to my specific adapter type, then I can get the number of columns and use that for my layout calculations. If it's not the right type of adapter, I just treat it as if there's only one column.
Now while this approach seems to work, it muddies up the API a little as getItemCount()
no longer returns the count of actual items, but rather the count of views, which may be confusing to a user. (I wish they had named it getViewCount()
instead.) It also means again, that LayoutManager only works with a specific Adapter type.
I had also considered making it look like multiple columns by using a horizontal LinearLayout to represent an entire row, then using that in a regular list, but that limited our flexibility (i.e. can't do fixed rows/columns, etc.) so we abandoned it.
I'm wondering if I'm approaching this wrong and/or if there's an API I can already use for this. Is there such a thing, or am I on the correct approach?