Created
February 2, 2017 16:01
-
-
Save mduisenov/52f42cc337772cc9882af2ee3ed0bcf8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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