I want to create RecyclerView with items which has always the same height but different width. It's quite easy with Horizontal Recycler View, but I want to do that with Vertical Recycler View.
The result should look like this:
___________________________________________
| |
|[................] [......] [........] |
|[......................] [..............] |
|[.....] [.................] |
|[......................] [......] |
| |
-------------------------------------------
How can I achieve that? Or maybe there is something better than recycler view?
Using the approach suggested by Doron Yakovlev-Golani, I did it with this class:
public class LessonsLayoutManager extends StaggeredGridLayoutManager {
private Point mMeasuredDimension = new Point();
public LessonsLayoutManager() {
super(2, HORIZONTAL);
}
@Override
public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state,
int widthSpec, int heightSpec) {
final int widthSize = View.MeasureSpec.getSize(widthSpec) - (getPaddingRight() + getPaddingLeft());
int width = 0;
int height = 0;
int row = 0;
for (int i = 0; i < getItemCount(); i++) {
if (!measureScrapChild(recycler, i,
View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
mMeasuredDimension)) continue;
if (width + mMeasuredDimension.x > widthSize || mMeasuredDimension.x > widthSize) {
row++;
width = mMeasuredDimension.x;
} else {
width += mMeasuredDimension.x;
}
height += mMeasuredDimension.y;
}
setSpanCount(row);
setMeasuredDimension(View.MeasureSpec.getSize(widthSpec), height);
}
@Override
public boolean canScrollHorizontally() {
return false;
}
@Override
public boolean canScrollVertically() {
return false;
}
private boolean measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec, int heightSpec, Point measuredDimension) {
View view = null;
try {
view = recycler.getViewForPosition(position);
} catch (Exception ex) {
// try - catch is needed since support library version 24
}
if (view != null) {
RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
getPaddingLeft() + getPaddingRight(), p.width);
int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
getPaddingTop() + getPaddingBottom(), p.height);
view.measure(childWidthSpec, childHeightSpec);
measuredDimension.set(
view.getMeasuredWidth() + p.leftMargin + p.rightMargin,
view.getMeasuredHeight() + p.bottomMargin + p.topMargin
);
recycler.recycleView(view);
return true;
}
return false;
}
}
The result looks like this:
The short answer is the LayoutManager. It gives you a lot of options to do whatever layout you want in a RecyclerView. The layout you are describing seems to be a variant of what GridLayoutManager is providing, so perhaps start from there. You can see a solution to a similar problem in this question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With