Merge "Introduce a minimum scrollbar touch target size"
This commit is contained in:
committed by
Android (Google) Code Review
commit
9f5ce93549
@@ -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();
|
||||
|
||||
|
||||
@@ -155,6 +155,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;
|
||||
@@ -439,6 +448,14 @@ public class ViewConfiguration {
|
||||
return mScrollbarSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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" />
|
||||
|
||||
Reference in New Issue
Block a user