Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 40c4d5fc authored by Hyunyoung Song's avatar Hyunyoung Song Committed by Android (Google) Code Review
Browse files

Merge "RecyclerView Scrollbar is easier to target" into sc-dev

parents 2d6d8f89 58f49418
Loading
Loading
Loading
Loading
+24 −4
Original line number Original line Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.launcher3.views;


import static android.view.HapticFeedbackConstants.CLOCK_TICK;
import static android.view.HapticFeedbackConstants.CLOCK_TICK;


import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE;

import android.animation.ObjectAnimator;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources;
@@ -30,6 +32,7 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.RectF;
import android.os.Build;
import android.os.Build;
import android.util.AttributeSet;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Property;
import android.util.Property;
import android.view.MotionEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View;
@@ -54,9 +57,14 @@ import java.util.List;
 * The track and scrollbar that shows when you scroll the list.
 * The track and scrollbar that shows when you scroll the list.
 */
 */
public class RecyclerViewFastScroller extends View {
public class RecyclerViewFastScroller extends View {

    private static final String TAG = "RecyclerViewFastScroller";
    private static final int FASTSCROLL_THRESHOLD_MILLIS = 200;
    private static final boolean DEBUG = false;
    private static final int FASTSCROLL_THRESHOLD_MILLIS = 40;
    private static final int SCROLL_DELTA_THRESHOLD_DP = 4;
    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 Rect sTempRect = new Rect();


    private static final Property<RecyclerViewFastScroller, Integer> TRACK_WIDTH =
    private static final Property<RecyclerViewFastScroller, Integer> TRACK_WIDTH =
@@ -86,6 +94,7 @@ public class RecyclerViewFastScroller extends View {
    /** Keeps the last known scrolling delta/velocity along y-axis. */
    /** Keeps the last known scrolling delta/velocity along y-axis. */
    private int mDy = 0;
    private int mDy = 0;
    private final float mDeltaThreshold;
    private final float mDeltaThreshold;
    private final float mScrollbarLeftOffsetTouchDelegate;


    private final ViewConfiguration mConfig;
    private final ViewConfiguration mConfig;


@@ -157,6 +166,8 @@ public class RecyclerViewFastScroller extends View {


        mConfig = ViewConfiguration.get(context);
        mConfig = ViewConfiguration.get(context);
        mDeltaThreshold = res.getDisplayMetrics().density * SCROLL_DELTA_THRESHOLD_DP;
        mDeltaThreshold = res.getDisplayMetrics().density * SCROLL_DELTA_THRESHOLD_DP;
        mScrollbarLeftOffsetTouchDelegate = res.getDisplayMetrics().density
                * SCROLLBAR_LEFT_OFFSET_TOUCH_DELEGATE_DP;


        TypedArray ta =
        TypedArray ta =
                context.obtainStyledAttributes(attrs, R.styleable.RecyclerViewFastScroller, defStyleAttr, 0);
                context.obtainStyledAttributes(attrs, R.styleable.RecyclerViewFastScroller, defStyleAttr, 0);
@@ -239,6 +250,7 @@ public class RecyclerViewFastScroller extends View {
    public boolean handleTouchEvent(MotionEvent ev, Point offset) {
    public boolean handleTouchEvent(MotionEvent ev, Point offset) {
        int x = (int) ev.getX() - offset.x;
        int x = (int) ev.getX() - offset.x;
        int y = (int) ev.getY() - offset.y;
        int y = (int) ev.getY() - offset.y;

        switch (ev.getAction()) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_DOWN:
                // Keep track of the down positions
                // Keep track of the down positions
@@ -247,7 +259,7 @@ public class RecyclerViewFastScroller extends View {
                mDownTimeStampMillis = ev.getDownTime();
                mDownTimeStampMillis = ev.getDownTime();


                if ((Math.abs(mDy) < mDeltaThreshold &&
                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
                    // now the touch events are being passed to the {@link WidgetCell} until the
                    // touch sequence goes over the touch slop.
                    // touch sequence goes over the touch slop.
                    mRv.stopScroll();
                    mRv.stopScroll();
@@ -293,6 +305,13 @@ public class RecyclerViewFastScroller extends View {
                }
                }
                break;
                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;
        return mIsDragging;
    }
    }


@@ -401,7 +420,8 @@ public class RecyclerViewFastScroller extends View {
     * Returns whether the specified x position is near the scroll bar.
     * Returns whether the specified x position is near the scroll bar.
     */
     */
    public boolean isNearScrollBar(int x) {
    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) {
    private void animatePopupVisibility(boolean visible) {