Skip to content

Commit 357b98d

Browse files
committed
[Feature] Use 48dp as min touch target size and handle it properly.
1 parent d4d5fe5 commit 357b98d

2 files changed

Lines changed: 41 additions & 17 deletions

File tree

library/src/main/java/me/zhanghai/android/fastscroll/FastScroller.java

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838

3939
public class FastScroller {
4040

41-
private final int mScrollbarSlop;
41+
private final int mMinTouchTargetSize;
4242
private final int mTouchSlop;
4343

4444
@NonNull
@@ -82,7 +82,8 @@ public FastScroller(@NonNull ViewGroup view, @NonNull ViewHelper viewHelper,
8282
@NonNull Drawable thumbDrawable, @NonNull Consumer<TextView> popupStyle,
8383
@NonNull AnimationHelper animationHelper) {
8484

85-
mScrollbarSlop = view.getResources().getDimensionPixelOffset(R.dimen.afs_scrollbar_slop);
85+
mMinTouchTargetSize = view.getResources().getDimensionPixelSize(
86+
R.dimen.afs_min_touch_target_size);
8687
Context context = view.getContext();
8788
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
8889

@@ -282,9 +283,9 @@ private boolean onTouchEvent(@NonNull MotionEvent event) {
282283
mDownX = eventX;
283284
mDownY = eventY;
284285

285-
if (mTrackView.getAlpha() > 0 && isInsideView(mTrackView, eventX, eventY)) {
286+
if (mTrackView.getAlpha() > 0 && isInView(mTrackView, eventX, eventY)) {
286287
mDragStartY = eventY;
287-
if (isInsideView(mThumbView, eventX, eventY)) {
288+
if (isInViewTouchTarget(mThumbView, eventX, eventY)) {
288289
mDragStartThumbOffset = mThumbOffset;
289290
} else {
290291
mDragStartThumbOffset = (int) (eventY - padding.top - mThumbHeight / 2f);
@@ -295,9 +296,9 @@ private boolean onTouchEvent(@NonNull MotionEvent event) {
295296
break;
296297
case MotionEvent.ACTION_MOVE:
297298

298-
if (!mDragging && isNearView(mTrackView, mDownX, mDownY)
299+
if (!mDragging && isInViewTouchTarget(mTrackView, mDownX, mDownY)
299300
&& Math.abs(eventY - mDownY) > mTouchSlop) {
300-
if (isNearView(mThumbView, mDownX, mDownY)) {
301+
if (isInViewTouchTarget(mThumbView, mDownX, mDownY)) {
301302
mDragStartY = mLastY;
302303
mDragStartThumbOffset = mThumbOffset;
303304
} else {
@@ -325,18 +326,41 @@ private boolean onTouchEvent(@NonNull MotionEvent event) {
325326
return mDragging;
326327
}
327328

328-
private boolean isInsideView(@NonNull View view, float x, float y) {
329-
x += mView.getScrollX();
330-
y += mView.getScrollY();
331-
return x >= view.getLeft() && x < view.getRight() && y >= view.getTop()
332-
&& y < view.getBottom();
329+
private boolean isInView(@NonNull View view, float x, float y) {
330+
int scrollX = mView.getScrollX();
331+
int scrollY = mView.getScrollY();
332+
return x >= view.getLeft() - scrollX && x < view.getRight() - scrollX
333+
&& y >= view.getTop() - scrollY && y < view.getBottom() - scrollY;
334+
}
335+
336+
private boolean isInViewTouchTarget(@NonNull View view, float x, float y) {
337+
int scrollX = mView.getScrollX();
338+
int scrollY = mView.getScrollY();
339+
return isInTouchTarget(x, view.getLeft() - scrollX, view.getRight() - scrollX, 0,
340+
mView.getWidth())
341+
&& isInTouchTarget(y, view.getTop() - scrollY, view.getBottom() - scrollY, 0,
342+
mView.getHeight());
333343
}
334344

335-
private boolean isNearView(@NonNull View view, float x, float y) {
336-
x += mView.getScrollX();
337-
y += mView.getScrollY();
338-
return x >= view.getLeft() - mScrollbarSlop && x < view.getRight() + mScrollbarSlop
339-
&& y >= view.getTop() - mScrollbarSlop && y < view.getBottom() + mScrollbarSlop;
345+
private boolean isInTouchTarget(float position, int viewStart, int viewEnd, int parentStart,
346+
int parentEnd) {
347+
int viewSize = viewEnd - viewStart;
348+
if (viewSize >= mMinTouchTargetSize) {
349+
return position >= viewStart && position < viewEnd;
350+
}
351+
int touchTargetStart = viewStart - (mMinTouchTargetSize - viewSize) / 2;
352+
if (touchTargetStart < parentStart) {
353+
touchTargetStart = parentStart;
354+
}
355+
int touchTargetEnd = touchTargetStart + mMinTouchTargetSize;
356+
if (touchTargetEnd > parentEnd) {
357+
touchTargetEnd = parentEnd;
358+
touchTargetStart = touchTargetEnd - mMinTouchTargetSize;
359+
if (touchTargetStart < parentStart) {
360+
touchTargetStart = parentStart;
361+
}
362+
}
363+
return position >= touchTargetStart && position < touchTargetEnd;
340364
}
341365

342366
private void scrollToThumbOffset(int thumbOffset) {

library/src/main/res/values/dimens.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
<resources>
2020

21-
<dimen name="afs_scrollbar_slop">16dp</dimen>
21+
<dimen name="afs_min_touch_target_size">48dp</dimen>
2222

2323
<dimen name="afs_popup_min_size">88dp</dimen>
2424
<dimen name="afs_popup_margin_end">16dp</dimen>

0 commit comments

Comments
 (0)