35

I want a RecyclerView.LayoutManager that allows me to specify different span counts for different rows as a repeating pattern. For example 2,3 with 10 items would look like this:

  -------------
  |     |     |
  |     |     |
  -------------
  |   |   |   |
  |   |   |   |
  -------------
  |     |     |
  |     |     |
  -------------
  |   |   |   |
  |   |   |   |
  -------------

I can think of a way to hack this with GridLayoutManager and SpanSizeLookup but has anybody come up with a cleaner way to do this?

alexbirkett
  • 2,604
  • 2
  • 26
  • 30
  • 1
    Isn't that implemented in a [`StaggeredGridLayoutManager`?](https://developer.android.com/reference/android/support/v7/widget/StaggeredGridLayoutManager.html) – user4989692 Jun 29 '15 at 09:42

2 Answers2

69

To do what you want, you probably have to write your own LayoutManager.

I think this is easier:

    // Create a grid layout with 6 columns
    // (least common multiple of 2 and 3)
    GridLayoutManager layoutManager = new GridLayoutManager(this, 6);

    layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
        @Override
        public int getSpanSize(int position) {
            // 5 is the sum of items in one repeated section
            switch (position % 5) {
            // first two items span 3 columns each
            case 0:
            case 1:
                return 3;
            // next 3 items span 2 columns each
            case 2:
            case 3:
            case 4:
                return 2;
            }
            throw new IllegalStateException("internal error");
        }
    });

If your grid item needs to know its span size, you can find it like this within ViewHolder:

        // this line can return null when the view hasn't been added to the RecyclerView yet
        RecyclerView recyclerView = (RecyclerView) itemView.getParent();
        GridLayoutManager gridLayoutManager = (GridLayoutManager) recyclerView.getLayoutManager();
        int spanSize = gridLayoutManager.getSpanSizeLookup().getSpanSize(getLayoutPosition());
kris larson
  • 30,387
  • 5
  • 62
  • 74
  • this answer is easier http://stackoverflow.com/questions/33696096/setting-span-size-of-single-row-in-staggeredgridlayoutmanager?rq=1 – amorenew Aug 03 '16 at 13:02
  • It works great, Can we chek the span count in onBindView method at runtime? I want to show hide some views based on that. – Shajeel Afzal Sep 26 '16 at 15:44
  • I do not now why when change spanSize on some item, position is changed. for example 4th item come before changed span item( third one). – Mahdi Oct 24 '18 at 15:33
  • m getting can not resolve method getLayoutPosition – Raj Bedi Oct 17 '21 at 15:41
10

here's how to do it in kotlin:

val layoutManager= GridLayoutManager(activity, 3)
layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
    override fun getSpanSize(position: Int): Int {
        return when (position) {
            0 -> 3
            else -> 1
        }
    }
}
recyclerView.layoutManager = layoutManager

here, first we have created a grid layout manager with 3 columns, then we have specified the first will occupy the whole 3 columns while the rest take only one.

Amin Keshavarzian
  • 3,646
  • 1
  • 37
  • 38