diff options
| -rw-r--r-- | core/java/android/view/View.java | 102 | ||||
| -rw-r--r-- | core/java/android/view/ViewConfiguration.java | 17 | ||||
| -rw-r--r-- | core/res/res/values/config.xml | 3 | ||||
| -rw-r--r-- | core/res/res/values/symbols.xml | 1 | 
4 files changed, 101 insertions, 22 deletions
| diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index d46811753e39..0c6d9e318a99 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -5386,16 +5386,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback,          x += getScrollX();          y += getScrollY();          if (isVerticalScrollBarEnabled() && !isVerticalScrollBarHidden()) { -            final Rect bounds = mScrollCache.mScrollBarBounds; -            getVerticalScrollBarBounds(bounds); -            if (bounds.contains((int)x, (int)y)) { +            final Rect touchBounds = mScrollCache.mScrollBarTouchBounds; +            getVerticalScrollBarBounds(null, touchBounds); +            if (touchBounds.contains((int) x, (int) y)) {                  return true;              }          }          if (isHorizontalScrollBarEnabled()) { -            final Rect bounds = mScrollCache.mScrollBarBounds; -            getHorizontalScrollBarBounds(bounds); -            if (bounds.contains((int)x, (int)y)) { +            final Rect touchBounds = mScrollCache.mScrollBarTouchBounds; +            getHorizontalScrollBarBounds(null, touchBounds); +            if (touchBounds.contains((int) x, (int) y)) {                  return true;              }          } @@ -5414,7 +5414,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,              x += getScrollX();              y += getScrollY();              final Rect bounds = mScrollCache.mScrollBarBounds; -            getVerticalScrollBarBounds(bounds); +            final Rect touchBounds = mScrollCache.mScrollBarTouchBounds; +            getVerticalScrollBarBounds(bounds, touchBounds);              final int range = computeVerticalScrollRange();              final int offset = computeVerticalScrollOffset();              final int extent = computeVerticalScrollExtent(); @@ -5423,8 +5424,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,              final int thumbOffset = ScrollBarUtils.getThumbOffset(bounds.height(), thumbLength,                      extent, range, offset);              final int thumbTop = bounds.top + thumbOffset; -            if (x >= bounds.left && x <= bounds.right && y >= thumbTop -                    && y <= thumbTop + thumbLength) { +            final int adjust = Math.max(mScrollCache.scrollBarMinTouchTarget - thumbLength, 0) / 2; +            if (x >= touchBounds.left && x <= touchBounds.right +                    && y >= thumbTop - adjust && y <= thumbTop + thumbLength + adjust) {                  return true;              }          } @@ -5439,7 +5441,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,              x += getScrollX();              y += getScrollY();              final Rect bounds = mScrollCache.mScrollBarBounds; -            getHorizontalScrollBarBounds(bounds); +            final Rect touchBounds = mScrollCache.mScrollBarTouchBounds; +            getHorizontalScrollBarBounds(bounds, touchBounds);              final int range = computeHorizontalScrollRange();              final int offset = computeHorizontalScrollOffset();              final int extent = computeHorizontalScrollExtent(); @@ -5448,8 +5451,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,              final int thumbOffset = ScrollBarUtils.getThumbOffset(bounds.width(), thumbLength,                      extent, range, offset);              final int thumbLeft = bounds.left + thumbOffset; -            if (x >= thumbLeft && x <= thumbLeft + thumbLength && y >= bounds.top -                    && y <= bounds.bottom) { +            final int adjust = Math.max(mScrollCache.scrollBarMinTouchTarget - thumbLength, 0) / 2; +            if (x >= thumbLeft - adjust && x <= thumbLeft + thumbLength + adjust +                    && y >= touchBounds.top && y <= touchBounds.bottom) {                  return true;              }          } @@ -11752,7 +11756,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,                  if (mScrollCache.mScrollBarDraggingState                          == ScrollabilityCache.DRAGGING_VERTICAL_SCROLL_BAR) {                      final Rect bounds = mScrollCache.mScrollBarBounds; -                    getVerticalScrollBarBounds(bounds); +                    getVerticalScrollBarBounds(bounds, null);                      final int range = computeVerticalScrollRange();                      final int offset = computeVerticalScrollOffset();                      final int extent = computeVerticalScrollExtent(); @@ -11781,7 +11785,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,                  if (mScrollCache.mScrollBarDraggingState                          == ScrollabilityCache.DRAGGING_HORIZONTAL_SCROLL_BAR) {                      final Rect bounds = mScrollCache.mScrollBarBounds; -                    getHorizontalScrollBarBounds(bounds); +                    getHorizontalScrollBarBounds(bounds, null);                      final int range = computeHorizontalScrollRange();                      final int offset = computeHorizontalScrollOffset();                      final int extent = computeHorizontalScrollExtent(); @@ -15488,7 +15492,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,          }      } -    private void getHorizontalScrollBarBounds(Rect bounds) { +    private void getHorizontalScrollBarBounds(@Nullable Rect drawBounds, +            @Nullable Rect touchBounds) { +        final Rect bounds = drawBounds != null ? drawBounds : touchBounds; +        if (bounds == null) { +            return; +        }          final int inside = (mViewFlags & SCROLLBARS_OUTSIDE_MASK) == 0 ? ~0 : 0;          final boolean drawVerticalScrollBar = isVerticalScrollBarEnabled()                  && !isVerticalScrollBarHidden(); @@ -15501,13 +15510,31 @@ public class View implements Drawable.Callback, KeyEvent.Callback,          bounds.left = mScrollX + (mPaddingLeft & inside);          bounds.right = mScrollX + width - (mUserPaddingRight & inside) - verticalScrollBarGap;          bounds.bottom = bounds.top + size; + +        if (touchBounds == null) { +            return; +        } +        if (touchBounds != bounds) { +            touchBounds.set(bounds); +        } +        final int minTouchTarget = mScrollCache.scrollBarMinTouchTarget; +        if (touchBounds.height() < minTouchTarget) { +            final int adjust = (minTouchTarget - touchBounds.height()) / 2; +            touchBounds.bottom = Math.min(touchBounds.bottom + adjust, mScrollY + height); +            touchBounds.top = touchBounds.bottom - minTouchTarget; +        } +        if (touchBounds.width() < minTouchTarget) { +            final int adjust = (minTouchTarget - touchBounds.width()) / 2; +            touchBounds.left -= adjust; +            touchBounds.right = touchBounds.left + minTouchTarget; +        }      } -    private void getVerticalScrollBarBounds(Rect bounds) { +    private void getVerticalScrollBarBounds(@Nullable Rect bounds, @Nullable Rect touchBounds) {          if (mRoundScrollbarRenderer == null) { -            getStraightVerticalScrollBarBounds(bounds); +            getStraightVerticalScrollBarBounds(bounds, touchBounds);          } else { -            getRoundVerticalScrollBarBounds(bounds); +            getRoundVerticalScrollBarBounds(bounds != null ? bounds : touchBounds);          }      } @@ -15522,7 +15549,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,          bounds.bottom = mScrollY + height;      } -    private void getStraightVerticalScrollBarBounds(Rect bounds) { +    private void getStraightVerticalScrollBarBounds(@Nullable Rect drawBounds, +            @Nullable Rect touchBounds) { +        final Rect bounds = drawBounds != null ? drawBounds : touchBounds; +        if (bounds == null) { +            return; +        }          final int inside = (mViewFlags & SCROLLBARS_OUTSIDE_MASK) == 0 ? ~0 : 0;          final int size = getVerticalScrollbarWidth();          int verticalScrollbarPosition = mVerticalScrollbarPosition; @@ -15544,6 +15576,29 @@ public class View implements Drawable.Callback, KeyEvent.Callback,          bounds.top = mScrollY + (mPaddingTop & inside);          bounds.right = bounds.left + size;          bounds.bottom = mScrollY + height - (mUserPaddingBottom & inside); + +        if (touchBounds == null) { +            return; +        } +        if (touchBounds != bounds) { +            touchBounds.set(bounds); +        } +        final int minTouchTarget = mScrollCache.scrollBarMinTouchTarget; +        if (touchBounds.width() < minTouchTarget) { +            final int adjust = (minTouchTarget - touchBounds.width()) / 2; +            if (verticalScrollbarPosition == SCROLLBAR_POSITION_RIGHT) { +                touchBounds.right = Math.min(touchBounds.right + adjust, mScrollX + width); +                touchBounds.left = touchBounds.right - minTouchTarget; +            } else { +                touchBounds.left = Math.max(touchBounds.left + adjust, mScrollX); +                touchBounds.right = touchBounds.left + minTouchTarget; +            } +        } +        if (touchBounds.height() < minTouchTarget) { +            final int adjust = (minTouchTarget - touchBounds.height()) / 2; +            touchBounds.top -= adjust; +            touchBounds.bottom = touchBounds.top + minTouchTarget; +        }      }      /** @@ -15602,7 +15657,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,              if (mRoundScrollbarRenderer != null) {                  if (drawVerticalScrollBar) {                      final Rect bounds = cache.mScrollBarBounds; -                    getVerticalScrollBarBounds(bounds); +                    getVerticalScrollBarBounds(bounds, null);                      mRoundScrollbarRenderer.drawRoundScrollbars(                              canvas, (float) cache.scrollBar.getAlpha() / 255f, bounds);                      if (invalidate) { @@ -15618,7 +15673,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,                              computeHorizontalScrollOffset(),                              computeHorizontalScrollExtent(), false);                      final Rect bounds = cache.mScrollBarBounds; -                    getHorizontalScrollBarBounds(bounds); +                    getHorizontalScrollBarBounds(bounds, null);                      onDrawHorizontalScrollBar(canvas, scrollBar, bounds.left, bounds.top,                              bounds.right, bounds.bottom);                      if (invalidate) { @@ -15631,7 +15686,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,                              computeVerticalScrollOffset(),                              computeVerticalScrollExtent(), true);                      final Rect bounds = cache.mScrollBarBounds; -                    getVerticalScrollBarBounds(bounds); +                    getVerticalScrollBarBounds(bounds, null);                      onDrawVerticalScrollBar(canvas, scrollBar, bounds.left, bounds.top,                              bounds.right, bounds.bottom);                      if (invalidate) { @@ -24123,6 +24178,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,          public int scrollBarFadeDuration;          public int scrollBarSize; +        public int scrollBarMinTouchTarget;          public ScrollBarDrawable scrollBar;          public float[] interpolatorValues;          public View host; @@ -24151,6 +24207,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,          private int mLastColor;          public final Rect mScrollBarBounds = new Rect(); +        public final Rect mScrollBarTouchBounds = new Rect();          public static final int NOT_DRAGGING = 0;          public static final int DRAGGING_VERTICAL_SCROLL_BAR = 1; @@ -24162,6 +24219,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,          public ScrollabilityCache(ViewConfiguration configuration, View host) {              fadingEdgeLength = configuration.getScaledFadingEdgeLength();              scrollBarSize = configuration.getScaledScrollBarSize(); +            scrollBarMinTouchTarget = configuration.getScaledMinScrollbarTouchTarget();              scrollBarDefaultDelayBeforeFade = ViewConfiguration.getScrollDefaultDelay();              scrollBarFadeDuration = ViewConfiguration.getScrollBarFadeDuration(); diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java index 0e753f39535d..5d01b4162c6f 100644 --- a/core/java/android/view/ViewConfiguration.java +++ b/core/java/android/view/ViewConfiguration.java @@ -156,6 +156,11 @@ public class ViewConfiguration {      private static final int TOUCH_SLOP = 8;      /** +     * Defines the minimum size of the touch target for a scrollbar in dips +     */ +    private static final int MIN_SCROLLBAR_TOUCH_TARGET = 48; + +    /**       * Distance the first touch can wander before we stop considering this event a double tap       * (in dips)       */ @@ -274,6 +279,7 @@ public class ViewConfiguration {      private final int mMaximumFlingVelocity;      private final int mScrollbarSize;      private final int mTouchSlop; +    private final int mMinScrollbarTouchTarget;      private final int mDoubleTapTouchSlop;      private final int mPagingTouchSlop;      private final int mDoubleTapSlop; @@ -302,6 +308,7 @@ public class ViewConfiguration {          mMaximumFlingVelocity = MAXIMUM_FLING_VELOCITY;          mScrollbarSize = SCROLL_BAR_SIZE;          mTouchSlop = TOUCH_SLOP; +        mMinScrollbarTouchTarget = MIN_SCROLLBAR_TOUCH_TARGET;          mDoubleTapTouchSlop = DOUBLE_TAP_TOUCH_SLOP;          mPagingTouchSlop = PAGING_TOUCH_SLOP;          mDoubleTapSlop = DOUBLE_TAP_SLOP; @@ -386,6 +393,8 @@ public class ViewConfiguration {                  com.android.internal.R.bool.config_ui_enableFadingMarquee);          mTouchSlop = res.getDimensionPixelSize(                  com.android.internal.R.dimen.config_viewConfigurationTouchSlop); +        mMinScrollbarTouchTarget = res.getDimensionPixelSize( +                com.android.internal.R.dimen.config_minScrollbarTouchTarget);          mPagingTouchSlop = mTouchSlop * 2;          mDoubleTapTouchSlop = mTouchSlop; @@ -440,6 +449,14 @@ public class ViewConfiguration {      }      /** +     * @return the minimum size of the scrollbar thumb's touch target in pixels +     * @hide +     */ +    public int getScaledMinScrollbarTouchTarget() { +        return mMinScrollbarTouchTarget; +    } + +    /**       * @return Duration of the fade when scrollbars fade away in milliseconds       */      public static int getScrollBarFadeDuration() { diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 581537d8dfa8..54c392f6eb2d 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1847,6 +1847,9 @@      -->      <fraction name="config_maximumScreenDimRatio">20%</fraction> +    <!-- Minimum size of the scrollbar thumb's touch target. --> +    <dimen name="config_minScrollbarTouchTarget">48dp</dimen> +      <!-- Base "touch slop" value used by ViewConfiguration as a           movement threshold where scrolling should begin. -->      <dimen name="config_viewConfigurationTouchSlop">8dp</dimen> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index f72906d25bc9..1324e383618d 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -423,6 +423,7 @@    <java-symbol type="dimen" name="accessibility_touch_slop" />    <java-symbol type="dimen" name="alert_dialog_round_padding"/> +  <java-symbol type="dimen" name="config_minScrollbarTouchTarget" />    <java-symbol type="dimen" name="config_prefDialogWidth" />    <java-symbol type="dimen" name="config_viewConfigurationTouchSlop" />    <java-symbol type="dimen" name="config_viewMinFlingVelocity" /> |