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);
}
Maybe I'm wrong (there's no good documentation about this out there yet), but I think you cannot achieve that with this layout manager. The staggered layout manager lets you place your views within spans, and if you place one that occupies the all of the spans, it will calculate the position for the next view based on the current one (without taking a look at the previous one).
In other words, if you place a view that occupies all of the spans, the layout manager will find the shortest span for the next view, and because you occupied all of them with the same view, the first span is the candidate.
I hope this helps you!
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
What you want to achieve is completely posible with GridLayoiutManager instead of StaggerdLayoutmanager. Here , I would have use Gridlayoutmanager as follows.
mGridLayoutManager = new GridLayoutManager(mContext,2,GridLayoutManager.HORIZONTAL,false);
mGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
if(position==0 && position ==1){
return 1;
}else {
return 2;
}
}
});
来源:https://stackoverflow.com/questions/26856036/how-to-reflow-items-in-a-recyclerview-with-the-staggeredgridlayoutmanager