Brianvdb
Brianvdb

Reputation: 676

RecyclerView layoutmanager for changing row and column span

I am looking to create the following layout (red sqaures does not really have to be squares, a custom fixed height is also fine). The layout seems very simple yet I did not find a layout manager which suits my needs.

wat i want

I tried the StaggeredGridLayoutManager but this only allows to set the span of either the column or the row, not both.

Is there floating around a custom layout manager which is able to do this? I have looked at TwoWayView but changing height seems to be problematic and the library is not being maintained.

Anyone having this problem and solved it?

Upvotes: 17

Views: 14975

Answers (2)

Nabin
Nabin

Reputation: 1541

Finally did it, it will help everyone who is trying to achieve any kind of patterns

I was looking for the same result but with one header and lazy loading footer. I tried @Kristyna answers of Nick Butcher Library too. But it has many issues like fast scrolling view disappear problem with the extra space or fixed cell height issue.

I found another library of Arasthel SpannedGridLayoutManager and tried to implement it. But it also has many issues like fixed height and footers extra space issue

Finally, after 5hr of digging Arasthel's SpannedGridLayoutManager, I fixed the issues and found my result.

My final edited forked library download from here SpannedGridLayoutManager.

enter image description here

In my case

  val adapter = GridItemAdapter()//This is your adapter
  val spannedGridLayoutManager = SpannedGridLayoutManager(orientation = VERTICAL, spans = 3)
  spannedGridLayoutManager.itemOrderIsStable = true
  recyclerview.layoutManager = spannedGridLayoutManager

And

  spannedGridLayoutManager.spanSizeLookup = SpannedGridLayoutManager.SpanSizeLookup { position ->
        when {
            position == 0 -> {
                /**
                 * 150f is now static 
                 * should calculate programmatically in runtime
                 * for to manage header hight for different resolution devices
                 */
                SpanSize(3, 1, 150f)
            }
            position % 7 == 1 ->
                SpanSize(2, 2)
            else ->
                SpanSize(1, 1)
        }
    }
  recyclerview.adapter = adapter

This spanSizeLookup logic may vary according to the requirement, for me I had set it randomly for testing purposes.

Upvotes: 6

kristyna
kristyna

Reputation: 2099

A little bit late, but it might help everyone else...

I was looking for the same and finally, after 2 days of googling I found a solution. Big thanks to Nick Butcher! His layout manager called SpannableGridLayoutManager is capable of doing this. In my case I was doing a pattern like your first two rows:

enter image description here

Solution is easy:

1. Download SpannableGridLayoutManager from here

For some reason I had to change this line:

while (availableSpace > 0 && lastVisiblePosition < lastItemPosition) {

to

while (lastVisiblePosition < lastItemPosition) {

to got the manager working.

2. Set SpannableGridLayoutManger to your RecyclerView

In my case:

    SpannedGridLayoutManager manager = new SpannedGridLayoutManager(
            new SpannedGridLayoutManager.GridSpanLookup() {
                @Override
                public SpannedGridLayoutManager.SpanInfo getSpanInfo(int position) {
                    // Conditions for 2x2 items 
                    if (position % 6 == 0 || position % 6 == 4) {
                        return new SpannedGridLayoutManager.SpanInfo(2, 2);
                    } else {
                        return new SpannedGridLayoutManager.SpanInfo(1, 1);
                    }
                }
            },
            3, // number of columns
            1f // how big is default item
    );

Which gave me exactly what I wanted (numbers are position of item in adapter):

enter image description here

EDIT: error with styleable Put those lines into attrs.xml

<declare-styleable name="SpannedGridLayoutManager">
    <attr name="android:orientation" />
    <attr name="spanCount" />
    <attr name="aspectRatio" format="string" />
</declare-styleable>

Upvotes: 22

Related Questions