diff --git a/src/com/android/launcher3/views/RecyclerViewFastScroller.java b/src/com/android/launcher3/views/RecyclerViewFastScroller.java index 78916acd16..a88b8b7776 100644 --- a/src/com/android/launcher3/views/RecyclerViewFastScroller.java +++ b/src/com/android/launcher3/views/RecyclerViewFastScroller.java @@ -18,6 +18,8 @@ package com.android.launcher3.views; import static android.view.HapticFeedbackConstants.CLOCK_TICK; +import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE; + import android.animation.ObjectAnimator; import android.content.Context; import android.content.res.Resources; @@ -30,6 +32,7 @@ import android.graphics.Rect; import android.graphics.RectF; import android.os.Build; import android.util.AttributeSet; +import android.util.Log; import android.util.Property; import android.view.MotionEvent; import android.view.View; @@ -54,9 +57,14 @@ import java.util.List; * The track and scrollbar that shows when you scroll the list. */ public class RecyclerViewFastScroller extends View { - - private static final int FASTSCROLL_THRESHOLD_MILLIS = 200; + private static final String TAG = "RecyclerViewFastScroller"; + private static final boolean DEBUG = false; + private static final int FASTSCROLL_THRESHOLD_MILLIS = 40; private static final int SCROLL_DELTA_THRESHOLD_DP = 4; + + // Track is very narrow to target and correctly. This is especially the case if a user is + // using a hardware case. Even if x is offset by following amount, we consider it to be valid. + private static final int SCROLLBAR_LEFT_OFFSET_TOUCH_DELEGATE_DP = 5; private static final Rect sTempRect = new Rect(); private static final Property TRACK_WIDTH = @@ -86,6 +94,7 @@ public class RecyclerViewFastScroller extends View { /** Keeps the last known scrolling delta/velocity along y-axis. */ private int mDy = 0; private final float mDeltaThreshold; + private final float mScrollbarLeftOffsetTouchDelegate; private final ViewConfiguration mConfig; @@ -157,6 +166,8 @@ public class RecyclerViewFastScroller extends View { mConfig = ViewConfiguration.get(context); mDeltaThreshold = res.getDisplayMetrics().density * SCROLL_DELTA_THRESHOLD_DP; + mScrollbarLeftOffsetTouchDelegate = res.getDisplayMetrics().density + * SCROLLBAR_LEFT_OFFSET_TOUCH_DELEGATE_DP; TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.RecyclerViewFastScroller, defStyleAttr, 0); @@ -239,6 +250,7 @@ public class RecyclerViewFastScroller extends View { public boolean handleTouchEvent(MotionEvent ev, Point offset) { int x = (int) ev.getX() - offset.x; int y = (int) ev.getY() - offset.y; + switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: // Keep track of the down positions @@ -247,7 +259,7 @@ public class RecyclerViewFastScroller extends View { mDownTimeStampMillis = ev.getDownTime(); if ((Math.abs(mDy) < mDeltaThreshold && - mRv.getScrollState() != RecyclerView.SCROLL_STATE_IDLE)) { + mRv.getScrollState() != SCROLL_STATE_IDLE)) { // now the touch events are being passed to the {@link WidgetCell} until the // touch sequence goes over the touch slop. mRv.stopScroll(); @@ -293,6 +305,13 @@ public class RecyclerViewFastScroller extends View { } break; } + if (DEBUG) { + Log.d(TAG, (ev.getAction() == MotionEvent.ACTION_DOWN ? "\n" : "") + + "handleTouchEvent " + MotionEvent.actionToString(ev.getAction()) + + " (" + x + "," + y + ")" + " isDragging=" + mIsDragging + + " mIgnoreDragGesture=" + mIgnoreDragGesture); + + } return mIsDragging; } @@ -401,7 +420,8 @@ public class RecyclerViewFastScroller extends View { * Returns whether the specified x position is near the scroll bar. */ public boolean isNearScrollBar(int x) { - return x >= (getWidth() - mMaxWidth) / 2 && x <= (getWidth() + mMaxWidth) / 2; + return x >= (getWidth() - mMaxWidth) / 2 - mScrollbarLeftOffsetTouchDelegate + && x <= (getWidth() + mMaxWidth) / 2; } private void animatePopupVisibility(boolean visible) {