Skip to content

Instantly share code, notes, and snippets.

@Miha-x64
Forked from heinrichreimer/LICENSE
Last active May 24, 2023 16:37
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Miha-x64/c5f94274b813ba8b0cbd94a99bf74397 to your computer and use it in GitHub Desktop.
Save Miha-x64/c5f94274b813ba8b0cbd94a99bf74397 to your computer and use it in GitHub Desktop.
LinearLayoutManager which distributes available space equally between all items. Changed: works also when items are added or removed.
package net.aquadc.recycler;
import android.content.Context;
import android.graphics.Rect;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
/**
* LinearLayoutManager which distributes available space equally between all items.
* Original https://gist.github.com/heinrichreimer/39f9d2f9023a184d96f8
* Fixed fork https://gist.github.com/Miha-x64/c5f94274b813ba8b0cbd94a99bf74397
*/
public class SpanningLinearLayoutManager extends LinearLayoutManager {
public SpanningLinearLayoutManager(Context context) {
super(context);
}
public SpanningLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
public SpanningLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
private final Rect insets = new Rect();
@Override
public void measureChild(View child, int widthUsed, int heightUsed) {
final RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) child.getLayoutParams();
calculateItemDecorationsForChild(child, insets);
widthUsed += insets.left + insets.right;
heightUsed += insets.top + insets.bottom;
// if (shouldMeasureChild(child, widthSpec, heightSpec, lp)) {
child.measure(
createWidthSpec(widthUsed, lp, false),
createHeightSpec(heightUsed, lp, false)
);
// }
}
@Override
public void measureChildWithMargins(View child, int widthUsed, int heightUsed) {
final RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) child.getLayoutParams();
calculateItemDecorationsForChild(child, insets);
widthUsed += insets.left + insets.right;
heightUsed += insets.top + insets.bottom;
// if (shouldMeasureChild(child, widthSpec, heightSpec, lp)) {
child.measure(
createWidthSpec(widthUsed, lp, true),
createHeightSpec(heightUsed, lp, true)
);
// }
}
private int createWidthSpec(int widthUsed, RecyclerView.LayoutParams lp, boolean withMargins) {
int padding = getPaddingLeft() + getPaddingRight() + widthUsed;
if (withMargins) padding += lp.leftMargin + lp.rightMargin;
return getOrientation() == HORIZONTAL
? View.MeasureSpec.makeMeasureSpec((int) Math.round(getHorizontalSpace() / (double) getItemCount()), View.MeasureSpec.EXACTLY)
: getChildMeasureSpec(getWidth(), getWidthMode(), padding, lp.width, /*canScrollHorizontally*/ false);
}
private int createHeightSpec(int heightUsed, RecyclerView.LayoutParams lp, boolean withMargins) {
int padding = getPaddingTop() + getPaddingBottom() + heightUsed;
if (withMargins) padding += lp.topMargin + lp.bottomMargin;
return getOrientation() == VERTICAL
? View.MeasureSpec.makeMeasureSpec((int) Math.round(getVerticalSpace() / (double) getItemCount()), View.MeasureSpec.EXACTLY)
: getChildMeasureSpec(getHeight(), getHeightMode(), padding, lp.height, /*canScrollVertically*/ false);
}
@Override
public boolean canScrollVertically() {
return false;
}
@Override
public boolean canScrollHorizontally() {
return false;
}
private int getHorizontalSpace() {
return getWidth() - getPaddingRight() - getPaddingLeft();
}
private int getVerticalSpace() {
return getHeight() - getPaddingBottom() - getPaddingTop();
}
}
@achatina
Copy link

Works better than original gist. Thanks!

@Vibinreji
Copy link

Thankyou very much.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment