5

I use GridLayoutManager to place items in RecyclerView vertically. Each item oocupies one span. Now I want some items to end current row, so next item is placed on new row below it. Each item must can occupy only one span, so that they're all same width.

Example:

enter image description here

The item[4] would be placed on next row, not after item[3]. Space after item[3] shall be left unused.

I tried to use SpanSizeLookup, but its span index doesn't make any sense to me and any value doesn't seem to do anything.

Can someone suggest solution?

Pointer Null
  • 39,597
  • 13
  • 90
  • 111
  • Do you override the getItemViewType? – matrix Feb 19 '18 at 09:33
  • setSpanSizeLookup is working – Pavya Feb 19 '18 at 09:36
  • @matrix: yes in Adapter, does it matter? – Pointer Null Feb 19 '18 at 09:46
  • I mean you can have lets say an enum with 2 values{ ONE_BOX, THREE_BOX} and then you create the viewHolder in both cases but you will need 2 layouts. I mean I do not think you can really achieve what you want with 1 layout and actually "force" the manager to decide when an item should go to another line. – matrix Feb 19 '18 at 09:52
  • That's not solution to use different item types when you only need some logic for placement. In RecyclerView you can insert/remove items dynamically, then items animate to their new positions, and all would be broken if I forced some item to occupy 3 spans. Besides I already have like 20 item types, and can't make different layout versions for 2 or 3 spans. – Pointer Null Feb 19 '18 at 09:55
  • @PointerNull Did you find solution? – andreich Dec 03 '19 at 11:21
  • I accomplished this by adding a zero-height all-column-spanning element to the list of content items whenever I needed a column break. I had to write a layout manager class to handle this but I already had one for adding section headers that spanned all columns. It's not a direct or elegant solution but it does accomplish the task without having to do special formatting when having the last item in a row span the remaining columns. – David Rector Jan 10 '23 at 00:24

1 Answers1

1
GridLayoutManager manager = new GridLayoutManager(getContext(), 3, LinearLayoutManager.VERTICAL, false);
    manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
        @Override
        public int getSpanSize(int position) {
            return position == 3 ? 3 : 1;
        }
});

Span size is 1 per default for each element, just return the desired span size for the position in custom span lookup.

artkoenig
  • 7,117
  • 2
  • 40
  • 61
  • 1
    Thanks, I know about this option, but then the layout width of the item is stretched to fit width of 3 items. I want the item to occupy only width of single span. – Pointer Null Feb 19 '18 at 10:10
  • Please provide an example where I can see the your actual problem (animation issues etc.) with this solution. – artkoenig Feb 19 '18 at 10:19
  • We can place item on new line based only on its position? Can we take into account item's properties for instance its category? – QuarK Feb 11 '22 at 12:07
  • This is not a useful answer because in addition to making the item after the item that is spanning more than one column, it is also, and incorrectly stretching the item that spans multiple columns, which is specifically unwanted in this case. – David Rector Jan 09 '23 at 23:25