GridLayoutManager with different column count per row
Asked Answered
E

2

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

Enzymology answered 6/3, 2017 at 15:53 Comment(0)
T
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.

Treachery answered 11/4, 2017 at 7:39 Comment(2)
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 caseEnzymology
@Enzymology Yes, you have to make some calculations in any way :)Treachery
D
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()
}
Denudation answered 2/2, 2021 at 9:56 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.