Skip to content

Instantly share code, notes, and snippets.

@mduisenov
Created February 2, 2017 16:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mduisenov/52f42cc337772cc9882af2ee3ed0bcf8 to your computer and use it in GitHub Desktop.
Save mduisenov/52f42cc337772cc9882af2ee3ed0bcf8 to your computer and use it in GitHub Desktop.
package ui.widget;
import android.content.Context;
import android.graphics.Rect;
import android.support.annotation.DimenRes;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.View;
/**
* grid space item decorator
*/
public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {
private static final int VERTICAL = 1;
private int halfSpacing;
private int orientation;
private int spacing;
private int spanCount;
public GridSpacingItemDecoration(final int spacing) {
this.orientation = -1;
this.spanCount = -1;
this.spacing = spacing;
this.halfSpacing = this.spacing / 2;
}
public GridSpacingItemDecoration(final Context context, @DimenRes final int i) {
this(Math.round(context.getResources().getDimension(i) / context.getResources().getDisplayMetrics().density));
}
@Override
public void getItemOffsets(final Rect rect, final View view, final RecyclerView recyclerView, final RecyclerView.State state) {
super.getItemOffsets(rect, view, recyclerView, state);
if (this.orientation == -1) {
this.orientation = this.getOrientation(recyclerView);
}
if (this.spanCount == -1) {
this.spanCount = this.getTotalSpan(recyclerView);
}
final int itemCount = recyclerView.getLayoutManager().getItemCount();
final int childAdapterPosition = recyclerView.getChildAdapterPosition(view);
final int itemSpanSize = this.getItemSpanSize(recyclerView, childAdapterPosition);
final int itemSpanIndex = this.getItemSpanIndex(recyclerView, childAdapterPosition);
if (this.spanCount < 1) {
return;
}
this.setSpacings(rect, recyclerView, itemCount, childAdapterPosition, itemSpanSize, itemSpanIndex);
}
protected int getItemSpanIndex(final RecyclerView recyclerView, final int n) {
final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
return ((GridLayoutManager) layoutManager).getSpanSizeLookup().getSpanIndex(n, this.spanCount);
}
if (layoutManager instanceof StaggeredGridLayoutManager) {
return n % this.spanCount;
}
if (layoutManager instanceof LinearLayoutManager) {
return 0;
}
return -1;
}
protected int getItemSpanSize(final RecyclerView recyclerView, int spanSize) {
final int n = VERTICAL;
final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
spanSize = ((GridLayoutManager) layoutManager).getSpanSizeLookup().getSpanSize(spanSize);
} else {
spanSize = n;
if (!(layoutManager instanceof StaggeredGridLayoutManager)) {
spanSize = n;
if (!(layoutManager instanceof LinearLayoutManager)) {
return -1;
}
}
}
return spanSize;
}
protected int getOrientation(final RecyclerView recyclerView) {
final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if (layoutManager instanceof LinearLayoutManager) {
return ((LinearLayoutManager) layoutManager).getOrientation();
}
if (layoutManager instanceof GridLayoutManager) {
return ((GridLayoutManager) layoutManager).getOrientation();
}
if (layoutManager instanceof StaggeredGridLayoutManager) {
return ((StaggeredGridLayoutManager) layoutManager).getOrientation();
}
return 1;
}
protected int getTotalSpan(final RecyclerView recyclerView) {
final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
return ((GridLayoutManager) layoutManager).getSpanCount();
}
if (layoutManager instanceof StaggeredGridLayoutManager) {
return ((StaggeredGridLayoutManager) layoutManager).getSpanCount();
}
if (layoutManager instanceof LinearLayoutManager) {
return VERTICAL;
}
return -1;
}
protected boolean isBottomEdge(final RecyclerView recyclerView, final int n, final int n2, final int n3, final int n4) {
final boolean b = true;
boolean b2 = true;
boolean lastItemEdgeValid;
if (this.orientation == VERTICAL) {
if (n2 < n - this.spanCount) {
b2 = false;
}
lastItemEdgeValid = this.isLastItemEdgeValid(b2, recyclerView, n, n2, n4);
} else {
lastItemEdgeValid = b;
if (n4 + n3 != this.spanCount) {
return false;
}
}
return lastItemEdgeValid;
}
protected boolean isFirstItemEdgeValid(final boolean b, final RecyclerView recyclerView, int n) {
int n2 = 0;
final int n3 = 0;
if (b) {
int n4 = n;
n = n3;
while (true) {
n2 = n;
if (n4 < 0) {
break;
}
n += this.getItemSpanSize(recyclerView, n4);
--n4;
}
}
return b && n2 <= this.spanCount;
}
protected boolean isLastItemEdgeValid(final boolean b, final RecyclerView recyclerView, final int n, int n2, final int n3) {
int n4 = 0;
final int n5 = 0;
if (b) {
int n6 = n2;
n2 = n5;
while (true) {
n4 = n2;
if (n6 >= n) {
break;
}
n2 += this.getItemSpanSize(recyclerView, n6);
++n6;
}
}
return b && n4 <= this.spanCount - n3;
}
protected boolean isLeftEdge(final RecyclerView recyclerView, final int n, final int n2, final int n3, final int n4) {
boolean b = false;
if (this.orientation == 1) {
return n4 == 0;
}
if (n2 == 0 || this.isFirstItemEdgeValid(n2 < this.spanCount, recyclerView, n2)) {
b = true;
}
return b;
}
protected boolean isRightEdge(final RecyclerView recyclerView, final int n, final int n2, final int n3, final int n4) {
boolean b = false;
if (this.orientation == VERTICAL) {
return n4 + n3 == this.spanCount;
}
if (n2 >= n - this.spanCount) {
b = true;
}
return this.isLastItemEdgeValid(b, recyclerView, n, n2, n4);
}
protected boolean isTopEdge(final RecyclerView recyclerView, final int n, final int n2, final int n3, final int n4) {
boolean b = false;
boolean b2 = true;
if (this.orientation == 1) {
if (n2 == 0 || this.isFirstItemEdgeValid(n2 < this.spanCount, recyclerView, n2)) {
b = true;
}
return b;
}
if (n4 != 0) {
b2 = false;
}
return b2;
}
protected void setSpacings(final Rect rect, final RecyclerView recyclerView, final int n, final int n2, final int n3, final int n4) {
rect.top = this.halfSpacing;
rect.bottom = this.halfSpacing;
rect.left = this.halfSpacing;
rect.right = this.halfSpacing;
if (this.isTopEdge(recyclerView, n, n2, n3, n4)) {
rect.top = this.spacing;
}
if (this.isLeftEdge(recyclerView, n, n2, n3, n4)) {
rect.left = this.spacing;
}
if (this.isRightEdge(recyclerView, n, n2, n3, n4)) {
rect.right = this.spacing;
}
if (this.isBottomEdge(recyclerView, n, n2, n3, n4)) {
rect.bottom = this.spacing;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment