Skip to content

Commit 93c620f

Browse files
author
Rafael Dominiquini
committed
Add list separator
1 parent 387c24b commit 93c620f

File tree

1 file changed

+200
-0
lines changed

1 file changed

+200
-0
lines changed
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
package com.timehop.stickyheadersrecyclerview.decorators;
2+
3+
import android.content.Context;
4+
import android.graphics.Rect;
5+
import android.support.annotation.DimenRes;
6+
import android.support.v7.widget.GridLayoutManager;
7+
import android.support.v7.widget.LinearLayoutManager;
8+
import android.support.v7.widget.OrientationHelper;
9+
import android.support.v7.widget.RecyclerView;
10+
import android.support.v7.widget.StaggeredGridLayoutManager;
11+
import android.view.View;
12+
13+
/**
14+
* Created by Rafael Baboni Dominiquini on 30/06/16.
15+
*/
16+
public class RecyclerSpacingDecoration extends RecyclerView.ItemDecoration {
17+
18+
private int orientation = -1;
19+
private int spanCount = -1;
20+
21+
private int fullSpacing;
22+
private int halfSpacing;
23+
24+
public RecyclerSpacingDecoration(Context context, @DimenRes int spacingDimen) {
25+
26+
this(context.getResources().getDimensionPixelSize(spacingDimen));
27+
}
28+
29+
public RecyclerSpacingDecoration(int spacingPx) {
30+
31+
fullSpacing = spacingPx;
32+
halfSpacing = spacingPx / 2;
33+
}
34+
35+
@Override
36+
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
37+
38+
super.getItemOffsets(outRect, view, parent, state);
39+
40+
if (orientation == -1) {
41+
orientation = getOrientation(parent);
42+
}
43+
44+
if (spanCount == -1) {
45+
spanCount = getTotalSpan(parent);
46+
}
47+
48+
int childCount = parent.getLayoutManager().getItemCount();
49+
int childIndex = parent.getChildAdapterPosition(view);
50+
51+
int itemSpanSize = getItemSpanSize(parent, childIndex);
52+
int spanIndex = getItemSpanIndex(parent, childIndex);
53+
54+
if (spanCount > 0) {
55+
setSpacings(outRect, parent, childCount, childIndex, itemSpanSize, spanIndex);
56+
}
57+
}
58+
59+
protected void setSpacings(Rect outRect, RecyclerView parent, int childCount, int childIndex, int itemSpanSize, int spanIndex) {
60+
61+
outRect.top = 0;
62+
outRect.bottom = fullSpacing;
63+
outRect.left = halfSpacing;
64+
outRect.right = halfSpacing;
65+
66+
if (isTopEdge(parent, childCount, childIndex, itemSpanSize, spanIndex)) {
67+
outRect.top = fullSpacing;
68+
}
69+
70+
if (isLeftEdge(parent, childCount, childIndex, itemSpanSize, spanIndex)) {
71+
outRect.left = fullSpacing;
72+
}
73+
74+
if (isRightEdge(parent, childCount, childIndex, itemSpanSize, spanIndex)) {
75+
outRect.right = fullSpacing;
76+
}
77+
78+
if (isBottomEdge(parent, childCount, childIndex, itemSpanSize, spanIndex)) {
79+
outRect.bottom = fullSpacing;
80+
}
81+
}
82+
83+
protected int getTotalSpan(RecyclerView parent) {
84+
85+
RecyclerView.LayoutManager mgr = parent.getLayoutManager();
86+
if (mgr instanceof GridLayoutManager) {
87+
return ((GridLayoutManager) mgr).getSpanCount();
88+
} else if (mgr instanceof StaggeredGridLayoutManager) {
89+
return ((StaggeredGridLayoutManager) mgr).getSpanCount();
90+
} else if (mgr instanceof LinearLayoutManager) {
91+
return 1;
92+
}
93+
94+
return -1;
95+
}
96+
97+
protected int getItemSpanSize(RecyclerView parent, int childIndex) {
98+
99+
RecyclerView.LayoutManager mgr = parent.getLayoutManager();
100+
if (mgr instanceof GridLayoutManager) {
101+
return ((GridLayoutManager) mgr).getSpanSizeLookup().getSpanSize(childIndex);
102+
} else if (mgr instanceof StaggeredGridLayoutManager) {
103+
return 1;
104+
} else if (mgr instanceof LinearLayoutManager) {
105+
return 1;
106+
}
107+
108+
return -1;
109+
}
110+
111+
protected int getItemSpanIndex(RecyclerView parent, int childIndex) {
112+
113+
RecyclerView.LayoutManager mgr = parent.getLayoutManager();
114+
if (mgr instanceof GridLayoutManager) {
115+
return ((GridLayoutManager) mgr).getSpanSizeLookup().getSpanIndex(childIndex, spanCount);
116+
} else if (mgr instanceof StaggeredGridLayoutManager) {
117+
return childIndex % spanCount;
118+
} else if (mgr instanceof LinearLayoutManager) {
119+
return 0;
120+
}
121+
122+
return -1;
123+
}
124+
125+
protected int getOrientation(RecyclerView parent) {
126+
127+
RecyclerView.LayoutManager mgr = parent.getLayoutManager();
128+
if (mgr instanceof LinearLayoutManager) {
129+
return ((LinearLayoutManager) mgr).getOrientation();
130+
} else if (mgr instanceof GridLayoutManager) {
131+
return ((GridLayoutManager) mgr).getOrientation();
132+
} else if (mgr instanceof StaggeredGridLayoutManager) {
133+
return ((StaggeredGridLayoutManager) mgr).getOrientation();
134+
}
135+
136+
return OrientationHelper.VERTICAL;
137+
}
138+
139+
protected boolean isLeftEdge(RecyclerView parent, int childCount, int childIndex, int itemSpanSize, int spanIndex) {
140+
141+
if (orientation == OrientationHelper.VERTICAL) {
142+
return spanIndex == 0;
143+
} else {
144+
return (childIndex == 0) || isFirstItemEdgeValid((childIndex < spanCount), parent, childIndex);
145+
}
146+
}
147+
148+
protected boolean isRightEdge(RecyclerView parent, int childCount, int childIndex, int itemSpanSize, int spanIndex) {
149+
150+
if (orientation == OrientationHelper.VERTICAL) {
151+
return (spanIndex + itemSpanSize) == spanCount;
152+
} else {
153+
return isLastItemEdgeValid((childIndex >= childCount - spanCount), parent, childCount, childIndex, spanIndex);
154+
}
155+
}
156+
157+
protected boolean isTopEdge(RecyclerView parent, int childCount, int childIndex, int itemSpanSize, int spanIndex) {
158+
159+
if (orientation == OrientationHelper.VERTICAL) {
160+
return (childIndex == 0) || isFirstItemEdgeValid((childIndex < spanCount), parent, childIndex);
161+
} else {
162+
return spanIndex == 0;
163+
}
164+
}
165+
166+
protected boolean isBottomEdge(RecyclerView parent, int childCount, int childIndex, int itemSpanSize, int spanIndex) {
167+
168+
if (orientation == OrientationHelper.VERTICAL) {
169+
return isLastItemEdgeValid((childIndex >= childCount - spanCount), parent, childCount, childIndex, spanIndex);
170+
} else {
171+
return (spanIndex + itemSpanSize) == spanCount;
172+
}
173+
}
174+
175+
protected boolean isFirstItemEdgeValid(boolean isOneOfFirstItems, RecyclerView parent, int childIndex) {
176+
177+
int totalSpanArea = 0;
178+
179+
if (isOneOfFirstItems) {
180+
for (int i = childIndex; i >= 0; i--) {
181+
totalSpanArea = totalSpanArea + getItemSpanSize(parent, i);
182+
}
183+
}
184+
185+
return isOneOfFirstItems && totalSpanArea <= spanCount;
186+
}
187+
188+
protected boolean isLastItemEdgeValid(boolean isOneOfLastItems, RecyclerView parent, int childCount, int childIndex, int spanIndex) {
189+
190+
int totalSpanRemaining = 0;
191+
192+
if (isOneOfLastItems) {
193+
for (int i = childIndex; i < childCount; i++) {
194+
totalSpanRemaining = totalSpanRemaining + getItemSpanSize(parent, i);
195+
}
196+
}
197+
198+
return isOneOfLastItems && (totalSpanRemaining <= spanCount - spanIndex);
199+
}
200+
}

0 commit comments

Comments
 (0)