9

I'm trying to build a RecyclerView with a GridLayoutManager which has a variable column count per row, something like this:

enter image description here

The sum of the width of all items in the same row will always be the screen width.

I tried to re-organize the list of items, grouping them by list of rows, and then inflating a LinearLayout per row. It didn't work quite well.

So I'm stuck and out of ideas. Any help would be really appreciated

moyo
  • 1,312
  • 1
  • 13
  • 29

2 Answers2

12

You can use GridLayoutManager. To have different column count in row you have to override setSpanSizeLookup.

Example:

//spanCount = 3 (just for example)
GridLayoutManager gridLayoutManager = new GridLayoutManager(getAppContext(), spanCount);
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
    @Override
    public int getSpanSize(int position) {
        //define span size for this position
        //some example for your first three items
        if(position == item1) {
            return 1; //item will take 1/3 space of row
        } else if(position == item2) {
            return 2; //you will have 2/3 space of row
        } else if(position == item3) {
            return 3; //you will have full row size item
        }
     }
});

I code sample above I just show have you can change item size. Pay attention that spanSize <= spanCount.

Volodymyr Yatsykiv
  • 3,181
  • 1
  • 24
  • 28
  • 1
    The problem is the spanCount is variable per row, but thanks anyway! I ended up using 12 as spanCount and making some calculations to adjust the widths. Usin 12, it will work fine with 1, 2, 3, and 4 elements per row. Not with 5 for example, but it's not a common case – moyo Apr 11 '17 at 09:02
  • @moyo Yes, you have to make some calculations in any way :) – Volodymyr Yatsykiv Apr 11 '17 at 11:56
0

I have similar situation and think it is a good choice to use kotlin: sealed class. You may set any spanSizeLookup for every item in your adapter list.

Example of setup spanSizeLookup for GridLayoutManager:

val spanCount = 2
val layoutManager =  GridLayoutManager(context, spanCount)
layoutManager.spanSizeLookup = object : SpanSizeLookup() {
    override fun getSpanSize(position: Int): Int {
        val item = adapter.getItemList().getOrNull(position) ?: return spanCount
        return when (item) {
            is ProfileItem.Header -> spanCount
            is ProfileItem.Status -> spanCount
            is ProfileItem.Progress -> spanCount
            is ProfileItem.Empty -> spanCount
            is ProfileItem.Item -> spanCount / 2
            is ProfileItem.Load -> spanCount / 2
        }
    }
}

My sealed class:

sealed class ProfileItem {
    object Header : ProfileItem()
    data class Status(var content: UserItem.User?) : ProfileItem()
    object Progress : ProfileItem()
    object Empty : ProfileItem()
    data class Item(val content: RecordItem.Record) : ProfileItem()
    object Load : ProfileItem()
}
SerjantArbuz
  • 982
  • 1
  • 12
  • 16