How to reflow items in a RecyclerView with the StaggeredGridLayoutManager

北城以北 提交于 2019-12-30 10:35:14

问题


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);
}

回答1:


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!




回答2:


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




回答3:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!