Skip to content

Commit a42101f

Browse files
committed
Added the ability to specify a view from the Header ViewHolder to make sticky instead of using the entire view
1 parent 9a388c0 commit a42101f

File tree

7 files changed

+61
-12
lines changed

7 files changed

+61
-12
lines changed

demo/src/main/java/com/devbrackets/android/recyclerextdemo/ui/fragment/HeaderAsChildListFragment.java

+8
Original file line numberDiff line numberDiff line change
@@ -119,5 +119,13 @@ public int getChildCount() {
119119
public long getHeaderId(int childPosition) {
120120
return items.get(childPosition).getOrder() / 10;
121121
}
122+
123+
/**
124+
* Specifying this will make only the number field from the header be sticky
125+
*/
126+
@Override
127+
public int getCustomStickyHeaderViewId() {
128+
return R.id.contacts_header_item_region_text_view;
129+
}
122130
}
123131
}

demo/src/main/java/com/devbrackets/android/recyclerextdemo/ui/viewholder/ContactsHeaderViewHolder.java

-4
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,4 @@ public void setText(String text) {
3434
public void setRegionText(String text) {
3535
regionTextView.setText(text);
3636
}
37-
38-
public int getStickyViewId() {
39-
return R.id.contacts_header_item_region_text_view;
40-
}
4137
}

demo/src/main/res/layout/list_item_simple_text.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
<TextView
2222
android:id="@+id/simple_text_text_view"
2323
android:layout_width="match_parent"
24-
android:layout_height="wrap_content"
25-
android:layout_gravity="center_vertical"
24+
android:layout_height="match_parent"
25+
android:gravity="center_vertical"
2626
android:paddingLeft="16dp"
2727
tools:ignore="RtlHardcoded,RtlSymmetry"
2828
tools:text="Lorem Ipsum Dolor Sit Amet"/>

library/src/main/java/com/devbrackets/android/recyclerext/adapter/RecyclerHeaderAdapter.java

+5
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,11 @@ public void showHeaderAsChild(boolean enabled) {
180180
core.showHeaderAsChild(enabled);
181181
}
182182

183+
@Override
184+
public int getCustomStickyHeaderViewId() {
185+
return 0;
186+
}
187+
183188
/**
184189
* Initializes the non-super components for the Adapter
185190
*/

library/src/main/java/com/devbrackets/android/recyclerext/adapter/RecyclerHeaderCursorAdapter.java

+5
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,11 @@ public void showHeaderAsChild(boolean enabled) {
209209
core.showHeaderAsChild(enabled);
210210
}
211211

212+
@Override
213+
public int getCustomStickyHeaderViewId() {
214+
return 0;
215+
}
216+
212217
/**
213218
* Initializes the non-super components for the Adapter
214219
*/

library/src/main/java/com/devbrackets/android/recyclerext/adapter/header/HeaderApi.java

+15
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,19 @@ public interface HeaderApi<H extends RecyclerView.ViewHolder, C extends Recycler
118118
* @param enabled True if the header should be treated as a child
119119
*/
120120
void showHeaderAsChild(boolean enabled);
121+
122+
/**
123+
* Retrieves the resource id for the view in the header
124+
* view holder to make sticky. By default this returns
125+
* the invalid resource id (0) and will use the entire
126+
* header view. Only use this if only a specific view
127+
* should remain sticky.
128+
* <p>
129+
* <b>NOTE:</b> This will only be used when a
130+
* {@link com.devbrackets.android.recyclerext.decoration.StickyHeaderDecoration}
131+
* has been specified
132+
*
133+
* @return The resource id for the view that will be sticky
134+
*/
135+
int getCustomStickyHeaderViewId();
121136
}

library/src/main/java/com/devbrackets/android/recyclerext/decoration/StickyHeaderDecoration.java

+26-6
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public enum LayoutOrientation {
5050
private AdapterDataObserver dataObserver;
5151
private StickyViewScrollListener scrollListener;
5252

53-
private int stickyHeaderStart = 0;
53+
private int stickyHeaderLeft, stickyHeaderTop;
5454
private long currentStickyId = Long.MIN_VALUE;
5555
private LayoutOrientation orientation = LayoutOrientation.VERTICAL;
5656

@@ -84,9 +84,7 @@ public StickyHeaderDecoration(RecyclerView parent) {
8484
@Override
8585
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
8686
if (stickyHeader != null) {
87-
int x = orientation == LayoutOrientation.HORIZONTAL ? stickyHeaderStart : 0;
88-
int y = orientation == LayoutOrientation.HORIZONTAL ? 0 : stickyHeaderStart;
89-
c.drawBitmap(stickyHeader, x, y, null);
87+
c.drawBitmap(stickyHeader, stickyHeaderLeft, stickyHeaderTop, null);
9088
}
9189
}
9290

@@ -114,7 +112,6 @@ public void clearStickyHeader() {
114112
}
115113

116114
stickyHeader = null;
117-
stickyHeaderStart = 0;
118115
currentStickyId = RecyclerView.NO_ID;
119116
}
120117

@@ -144,6 +141,10 @@ public LayoutOrientation getOrientation() {
144141
* @return The bitmap representing the drag view
145142
*/
146143
private Bitmap createStickyViewBitmap(View view) {
144+
//Makes sure the location opposite the scroll orientation is persisted
145+
stickyHeaderLeft = orientation == LayoutOrientation.HORIZONTAL ? 0 : view.getLeft();
146+
stickyHeaderTop = orientation == LayoutOrientation.VERTICAL ? 0 : view.getTop();
147+
147148
Rect stickyViewBounds = new Rect(0, 0, view.getRight() - view.getLeft(), view.getBottom() - view.getTop());
148149

149150
Bitmap bitmap = Bitmap.createBitmap(stickyViewBounds.width(), stickyViewBounds.height(), Bitmap.Config.ARGB_8888);
@@ -235,8 +236,19 @@ private void updateHeader(long headerId, int headerPosition) {
235236
return;
236237
}
237238

238-
stickyHeaderStart = 0;
239239
currentStickyId = headerId;
240+
241+
//Creates the actual sticky header (or view)
242+
int stickyViewId = getCustomStickyViewId();
243+
if (stickyViewId != 0) {
244+
View stickyView = holder.itemView.findViewById(stickyViewId);
245+
if (stickyView != null) {
246+
stickyHeader = createStickyViewBitmap(stickyView);
247+
return;
248+
}
249+
}
250+
251+
//If the user hasn't specified a sticky view id or it was null, use the entire view holder
240252
stickyHeader = createStickyViewBitmap(holder.itemView);
241253
}
242254

@@ -319,6 +331,14 @@ private int getHeaderViewType(int headerPosition) {
319331
return rawType | HeaderApi.HEADER_VIEW_TYPE_MASK;
320332
}
321333

334+
private int getCustomStickyViewId() {
335+
if (adapter instanceof RecyclerHeaderAdapter) {
336+
return ((RecyclerHeaderAdapter)adapter).getCustomStickyHeaderViewId();
337+
}
338+
339+
return ((RecyclerHeaderCursorAdapter) adapter).getCustomStickyHeaderViewId();
340+
}
341+
322342
/**
323343
* Retrieves the ViewHolder associated with the header at <code>headerPosition</code>.
324344
* If the ViewHolder returned from <code>parent</code> is null then a temporary ViewHolder

0 commit comments

Comments
 (0)