How to reflow items in a RecyclerView with the StaggeredGridLayoutManager

Niraj picture Niraj · Nov 11, 2014 · Viewed 10.3k times · Source

I'm playing around with the StaggeredGridLayoutManager and have something close to what I want. I have a horizontal staggered grid with 2 rows, where some items are the height of 1 row, and others span both rows. I want the single row height items to stack up and I thought that could be achieved by setting the gap strategy to GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS, but this does not appear to work.

Current:

 ___    ___    ___    ___
|___|  |   |  |___|  |   |
       |   |         |   |
       |___|         |___|

What I want:

 ___    ___    ___
|___|  |   |  |   |
 ___   |   |  |   |
|___|  |___|  |___|

The relevant code snippets:

Setting up the layout manager for the recyclerview:

StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.HORIZONTAL);
layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);
recyclerView.setLayoutManager(layoutManager);

Here's the onBindViewHolder for my custom adapter (this is just a simplified example). Basically I have an ImageView inside of a CardView (the CardView is set to wrap_content for height and width).

if(position%3==0) {
    ViewGroup.LayoutParams layoutParams = viewHolder.myImage.getLayoutParams();
    layoutParams.width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 200, context.getResources().getDisplayMetrics());
    layoutParams.height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 75, context.getResources().getDisplayMetrics());
    viewHolder.myImage.setLayoutParams(layoutParams);

    StaggeredGridLayoutManager.LayoutParams layoutParams1 = ((StaggeredGridLayoutManager.LayoutParams) viewHolder.itemView.getLayoutParams());
    layoutParams1.setFullSpan(false);
}
else {
    ViewGroup.LayoutParams layoutParams = viewHolder.myImage.getLayoutParams();
    layoutParams.width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 200, context.getResources().getDisplayMetrics());
    layoutParams.height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 200, context.getResources().getDisplayMetrics());
    viewHolder.myImage.setLayoutParams(layoutParams);

    StaggeredGridLayoutManager.LayoutParams layoutParams1 = ((StaggeredGridLayoutManager.LayoutParams) viewHolder.itemView.getLayoutParams());
    layoutParams1.setFullSpan(true);
}

Answer

yigit picture yigit · Nov 11, 2014

Doing this will requires not respecting position of items in the adapter which is hardly ever desired. Your best options is to re-order items in the adapter