Search code examples
androidandroid-recyclerviewgridlayoutmanagerstaggeredgridlayoutmanager

Gridlayoutmanager with 2x1 arrangement


I am trying to make a UI like the following using a gridlayoutmanager in a recyclerview:

+-------+ +-------+
|       | |       |
|       | |       |
|       | |       |
+-------+ +-------+
+-----------------+
|                 |
|                 |
+-----------------+

I am adjusting width in onBindViewHolder here:

int mode = (position+1)%4;
        int h_mul = 1, w_mul = 1;
        switch (mode){
            case 0:
                h_mul = w_mul = 2;
                break;
            case 2:
                w_mul = 2;
                break;
            case 3:
            case 1:
            default:
                h_mul = w_mul = 1;
                break;
        }
        mCardView.getLayoutParams().height = h_mul * mContext.getResources().getInteger(R.integer.video_tile_height);
        mCardView.getLayoutParams().width = w_mul * mContext.getResources().getInteger(R.integer.video_tile_width);

I have tried a number of approaches: 1. Horizontal gridlayoutmanager with setSpanSizeLookup:

    manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
        @Override
        public int getSpanSize(int position) {
            int mode = (position+1)%4;
            switch (mode){
                case 0:
                case 2:
                    return manager.getSpanCount();
                case 3:
                case 1:
                    return 1;
                default:
                    return -1;
            }
        }
    });

What i end up is this:

+------------+  +-----------------------------+ +------------+
|            |  |                             | |            |
|            |  |                             | |            |
|            |  |                             | |            |
|            |  |                             | |            |
|            |  |                             | |            |
+------------+  +-----------------------------+ +------------+

If i dont set span then it ends up like this:

+------------+               +---------------+
|            |               |               |
|            |               |               |
|            |               |               |
|            |               |               |
|            |               |               |
+------------+               +---------------+

+---------------------------+
|                           |
|                           |
|                           |
|                           |
|                           |
+---------------------------+

  1. Horizontal staggeredgridlayoutmanager. If is use

     StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) holder.itemView.getLayoutParams();
            layoutParams.setFullSpan(true);
    

Then it becomes same as

+------------+  +-----------------------------+ +------------+
|            |  |                             | |            |
|            |  |                             | |            |
|            |  |                             | |            |
|            |  |                             | |            |
|            |  |                             | |            |
+------------+  +-----------------------------+ +------------+

If i dont use full span initially it is perfect but if I scroll the recyclerview it becomes same as above:

+------------+  +-----------------------------+ +------------+
|            |  |                             | |            |
|            |  |                             | |            |
|            |  |                             | |            |
|            |  |                             | |            |
|            |  |                             | |            |
+------------+  +-----------------------------+ +------------+

I don't understand what is causing this. Can someone please point out what mistake I might be making?


Solution

  • You want to achieve a horizontal recycler view where you have repetition of these three boxes. But your approach to consider these 3 boxes as separate recycler item will not allow you to scroll them in group. What you have to do is define a separate layout which hold these 3 boxes in it. Then you supply data to it for 3 items and bind it in the view holder

    Basically you have to manipulate your data to be grouped liked this and then show it.

    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == GROUP_ITEM) {
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.group_item, parent, false);
            return new GroupViewHolder(view);
        } else if (viewType == SINGLE_ITEM) {
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.single_item, parent, false);
            return new SingleViewHolder(view);
        }
    
        return null;
    }
    
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof GroupViewHolder) {
            ((GroupViewHolder) holder).populateData(position);
        } else if (holder instanceof SingleViewHolder) {
          // populate your normal view.
        }
    }
    

    enter image description here