Skip to content

Commit b09cbc7

Browse files
Merge pull request #151 from Omega-R/feature/119_sticky_click
Feature/119 sticky click
2 parents 428d943 + 46d7077 commit b09cbc7

File tree

8 files changed

+118
-5
lines changed

8 files changed

+118
-5
lines changed

app/src/main/java/com/omega_r/omegarecyclerview/expandable_example/support_sticky/DefaultStickyAdapter.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ public void onBindStickyViewHolder(StickyViewHolder viewHolder, int position) {
4444
viewHolder.bind(getItem(position).getGroup().getYear());
4545
}
4646

47+
@Override
48+
public void onClickStickyViewHolder(long id) {
49+
// nothing
50+
}
51+
4752
class ExGroupViewHolder extends GroupViewHolder {
4853

4954
private TextView textView;

app/src/main/java/com/omega_r/omegarecyclerview/sticky_header_example/StickyHeaderAdapter.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import android.view.View;
66
import android.view.ViewGroup;
77
import android.widget.TextView;
8+
import android.widget.Toast;
89

910
import com.omega_r.libs.omegarecyclerview.OmegaRecyclerView;
1011
import com.omega_r.libs.omegarecyclerview.sticky_decoration.StickyAdapter;
@@ -14,9 +15,11 @@ public class StickyHeaderAdapter extends OmegaRecyclerView.Adapter<StickyHeaderA
1415
implements StickyAdapter<StickyHeaderAdapter.HeaderHolder> {
1516

1617
private LayoutInflater mInflater;
18+
private final Context mContext;
1719

1820
public StickyHeaderAdapter(Context context) {
1921
mInflater = LayoutInflater.from(context);
22+
mContext = context;
2023
}
2124

2225
@Override
@@ -51,12 +54,23 @@ public void onBindStickyViewHolder(HeaderHolder viewHolder, int position) {
5154
viewHolder.header.setText("Header " + getStickyId(position));
5255
}
5356

57+
@Override
58+
public void onClickStickyViewHolder(long id) {
59+
Toast.makeText(mContext, "onClickStickyViewHolder " + id, Toast.LENGTH_SHORT).show();
60+
}
61+
5462
static class ViewHolder extends OmegaRecyclerView.ViewHolder {
5563
public TextView item;
5664

5765
public ViewHolder(View itemView) {
5866
super(itemView);
5967
item = (TextView) itemView;
68+
item.setOnClickListener(new View.OnClickListener() {
69+
@Override
70+
public void onClick(View v) {
71+
Toast.makeText(v.getContext(), "Clicked", Toast.LENGTH_SHORT).show();
72+
}
73+
});
6074
}
6175
}
6276

omegarecyclerview/src/main/java/com/omega_r/libs/omegarecyclerview/OmegaRecyclerView.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public class OmegaRecyclerView extends ExpandedRecyclerView implements SwipeMenu
5656
private View mEmptyView;
5757
private int mEmptyViewId;
5858

59+
@Nullable
5960
private BaseStickyDecoration mBaseStickyDecoration;
6061
private BaseSpaceItemDecoration mBaseSpaceItemDecoration;
6162
private int mStickyMode = StickyAdapter.Mode.HEADER;
@@ -430,7 +431,15 @@ private void findEmptyView() {
430431

431432
@Override
432433
public boolean onInterceptTouchEvent(MotionEvent ev) {
433-
return mSwipeMenuHelper.handleInterceptTouchEvent(ev, super.onInterceptTouchEvent(ev));
434+
boolean result = mSwipeMenuHelper.handleInterceptTouchEvent(ev, super.onInterceptTouchEvent(ev));
435+
if (mBaseStickyDecoration != null && !result) return mBaseStickyDecoration.onTouchEvent(this, ev, result);
436+
return result;
437+
}
438+
439+
@Override
440+
public boolean onTouchEvent(MotionEvent e) {
441+
boolean result = super.onTouchEvent(e);
442+
return mBaseStickyDecoration == null ? result : mBaseStickyDecoration.onTouchEvent(this, e, result);
434443
}
435444

436445
@Override

omegarecyclerview/src/main/java/com/omega_r/libs/omegarecyclerview/header/HeaderFooterWrapperAdapter.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,12 @@ public void onBindStickyViewHolder(RecyclerView.ViewHolder viewHolder, int posit
270270
stickyAdapter.onBindStickyViewHolder(viewHolder, position);
271271
}
272272

273+
@Override
274+
public void onClickStickyViewHolder(long id) {
275+
StickyAdapter stickyAdapter = getStickyAdapter();
276+
if (stickyAdapter != null) stickyAdapter.onClickStickyViewHolder(id);
277+
}
278+
273279
@Override
274280
protected void tryNotifyItemRangeChanged(int positionStart, int itemCount, Object payload) {
275281
super.tryNotifyItemRangeChanged(positionStart + mHeaderArray.size(), itemCount, payload);

omegarecyclerview/src/main/java/com/omega_r/libs/omegarecyclerview/sticky_decoration/BaseStickyDecoration.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package com.omega_r.libs.omegarecyclerview.sticky_decoration;
22

3+
import android.view.MotionEvent;
4+
35
import androidx.annotation.CallSuper;
6+
import androidx.annotation.NonNull;
47
import androidx.annotation.Nullable;
58
import androidx.recyclerview.widget.RecyclerView;
69

10+
@SuppressWarnings("rawtypes")
711
public abstract class BaseStickyDecoration extends RecyclerView.ItemDecoration {
812

913
public static final long NO_STICKY_ID = -1L;
@@ -16,6 +20,10 @@ public BaseStickyDecoration(@Nullable StickyAdapter adapter) {
1620
mStickyAdapter = adapter;
1721
}
1822

23+
public boolean onTouchEvent(@NonNull RecyclerView parent, @NonNull MotionEvent ev, boolean defaultResult) {
24+
return defaultResult;
25+
}
26+
1927
@CallSuper
2028
public final void setStickyAdapter(@Nullable StickyAdapter adapter) {
2129
mStickyAdapter = adapter;
@@ -26,8 +34,7 @@ public final void setItemSpace(int itemSpace) {
2634
}
2735

2836
protected final boolean hasSticker(int position) {
29-
if (mStickyAdapter == null) return false;
30-
return mStickyAdapter.getStickyId(position) != NO_STICKY_ID;
37+
return mStickyAdapter != null && mStickyAdapter.getStickyId(position) != NO_STICKY_ID;
3138
}
3239

3340
}

omegarecyclerview/src/main/java/com/omega_r/libs/omegarecyclerview/sticky_decoration/HeaderStickyDecoration.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@
44
import android.view.View;
55
import android.view.ViewGroup;
66

7-
import com.omega_r.libs.omegarecyclerview.utils.ViewUtils;
8-
97
import androidx.annotation.NonNull;
108
import androidx.annotation.Nullable;
119
import androidx.recyclerview.widget.RecyclerView;
1210

1311
import static com.omega_r.libs.omegarecyclerview.utils.ViewUtils.isReverseLayout;
1412

13+
@SuppressWarnings("rawtypes")
1514
public class HeaderStickyDecoration extends StickyDecoration {
1615

1716
public HeaderStickyDecoration(StickyAdapter adapter) {

omegarecyclerview/src/main/java/com/omega_r/libs/omegarecyclerview/sticky_decoration/StickyAdapter.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ public interface StickyAdapter<T extends RecyclerView.ViewHolder> {
1111

1212
void onBindStickyViewHolder(T viewHolder, int position);
1313

14+
void onClickStickyViewHolder(long id);
1415

1516
interface Mode {
1617

omegarecyclerview/src/main/java/com/omega_r/libs/omegarecyclerview/sticky_decoration/StickyDecoration.java

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,80 @@
11
package com.omega_r.libs.omegarecyclerview.sticky_decoration;
22

33
import android.graphics.Canvas;
4+
import android.graphics.Rect;
5+
import android.view.MotionEvent;
46
import android.view.View;
57
import android.view.ViewGroup;
68

79
import androidx.annotation.NonNull;
810
import androidx.annotation.Nullable;
911
import androidx.recyclerview.widget.RecyclerView;
1012

13+
import java.util.HashMap;
14+
import java.util.Map;
15+
16+
import static androidx.recyclerview.widget.RecyclerView.NO_POSITION;
1117
import static com.omega_r.libs.omegarecyclerview.utils.ViewUtils.isReverseLayout;
18+
import static java.lang.Math.abs;
1219

20+
@SuppressWarnings("rawtypes")
1321
abstract class StickyDecoration extends BaseStickyDecoration {
1422

23+
private static final float CLICK_MOVE_BIAS = 150;
24+
25+
private final Map<Long, Rect> mStickyRectMap = new HashMap<>();
26+
private long mClickedStickyId = NO_STICKY_ID;
27+
private float mActionDownX;
28+
private float mActionDownY;
29+
1530
public StickyDecoration(@Nullable StickyAdapter adapter) {
1631
super(adapter);
1732
}
1833

34+
@Override
35+
public final boolean onTouchEvent(@NonNull RecyclerView parent, @NonNull MotionEvent ev, boolean defaultResult) {
36+
if (mStickyAdapter == null) return defaultResult;
37+
38+
RecyclerView.Adapter adapter = parent.getAdapter();
39+
if (adapter == null || adapter.getItemCount() == 0) return defaultResult;
40+
41+
switch (ev.getAction()) {
42+
case MotionEvent.ACTION_DOWN:
43+
mActionDownX = ev.getX();
44+
mActionDownY = ev.getY();
45+
mClickedStickyId = NO_STICKY_ID;
46+
return handleActionDown(parent, ev, defaultResult);
47+
case MotionEvent.ACTION_UP:
48+
if (mStickyAdapter != null && mClickedStickyId != NO_STICKY_ID) {
49+
float eventX = ev.getX();
50+
float eventY = ev.getY();
51+
if (abs(mActionDownX - eventX) <= CLICK_MOVE_BIAS && abs(mActionDownY - eventY) <= CLICK_MOVE_BIAS) {
52+
mStickyAdapter.onClickStickyViewHolder(mClickedStickyId);
53+
}
54+
}
55+
break;
56+
}
57+
return super.onTouchEvent(parent, ev, defaultResult);
58+
}
59+
60+
private boolean handleActionDown(@NonNull RecyclerView parent, @NonNull final MotionEvent ev, boolean defaultResult) {
61+
int eventX = (int) ev.getX();
62+
int eventY = (int) ev.getY();
63+
for (Long stickyId : mStickyRectMap.keySet()) {
64+
Rect rect = mStickyRectMap.get(stickyId);
65+
if (stickyId != NO_STICKY_ID && rect != null && !rect.isEmpty() && rect.contains(eventX, eventY)) {
66+
mClickedStickyId = stickyId;
67+
return true;
68+
}
69+
}
70+
return defaultResult;
71+
}
72+
1973
@Override
2074
public final void onDrawOver(@NonNull Canvas canvas, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
2175
super.onDrawOver(canvas, parent, state);
76+
invalidateRectMap();
77+
2278
int count = parent.getChildCount();
2379
long previousStickerId = -1;
2480
if (isReverseLayout(parent)) {
@@ -32,6 +88,12 @@ public final void onDrawOver(@NonNull Canvas canvas, @NonNull RecyclerView paren
3288
}
3389
}
3490

91+
private void invalidateRectMap() {
92+
for (Rect rect : mStickyRectMap.values()) {
93+
rect.setEmpty();
94+
}
95+
}
96+
3597
private long calculateStickerIdAndDrawIt(Canvas canvas, RecyclerView parent, boolean isReverseLayout,
3698
int layoutPos, long previousStickerId) {
3799
long previousId = previousStickerId;
@@ -66,13 +128,23 @@ && hasSticker(adapterPosition - 1)
66128
} else {
67129
top = getStickerTop(parent, isReverseLayout, childView, stickerView, adapterPosition, layoutPos);
68130
drawSticky(canvas, childView, stickyHolder, top);
131+
updateStickerRect(previousId, top, stickerView);
69132
}
70133
}
71134
}
72135
}
73136
return previousId;
74137
}
75138

139+
private void updateStickerRect(long stickyId, int stickerTop, View stickerView) {
140+
Rect rect = mStickyRectMap.get(stickyId);
141+
if (rect == null) {
142+
rect = new Rect();
143+
mStickyRectMap.put(stickyId, rect);
144+
}
145+
rect.set(stickerView.getLeft(), stickerTop, stickerView.getRight(), stickerTop + stickerView.getHeight());
146+
}
147+
76148
private void drawSticky(Canvas canvas, View childView, RecyclerView.ViewHolder stickyHolder, int top) {
77149
if (stickyHolder == null) return;
78150

0 commit comments

Comments
 (0)