diff options
| -rw-r--r-- | core/java/android/view/View.java | 4 | ||||
| -rw-r--r-- | core/java/android/widget/HorizontalScrollView.java | 45 | ||||
| -rw-r--r-- | core/java/android/widget/ScrollView.java | 44 |
3 files changed, 74 insertions, 19 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 1273b491d0e1..ba78f966b218 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -22164,6 +22164,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * and hardware acceleration. */ boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) { + // Clear the overscroll effect: + // TODO: Use internal API instead of overriding the existing RenderEffect + setRenderEffect(null); + final boolean hardwareAcceleratedCanvas = canvas.isHardwareAccelerated(); /* If an attached view draws to a HW canvas, it may use its RenderNode + DisplayList. * diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java index 97dbb1542717..6dedd12a2730 100644 --- a/core/java/android/widget/HorizontalScrollView.java +++ b/core/java/android/widget/HorizontalScrollView.java @@ -89,7 +89,7 @@ public class HorizontalScrollView extends FrameLayout { */ @NonNull @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124053130) - private EdgeEffect mEdgeGlowLeft = new EdgeEffect(getContext()); + private EdgeEffect mEdgeGlowLeft; /** * Tracks the state of the bottom edge glow. @@ -98,7 +98,7 @@ public class HorizontalScrollView extends FrameLayout { * setting it via reflection and they need to keep working until they target Q. */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124052619) - private EdgeEffect mEdgeGlowRight = new EdgeEffect(getContext()); + private EdgeEffect mEdgeGlowRight; /** * Position of the last motion event. @@ -186,6 +186,8 @@ public class HorizontalScrollView extends FrameLayout { public HorizontalScrollView( Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); + mEdgeGlowLeft = new EdgeEffect(context, attrs); + mEdgeGlowRight = new EdgeEffect(context, attrs); initScrollView(); final TypedArray a = context.obtainStyledAttributes( @@ -631,7 +633,15 @@ public class HorizontalScrollView extends FrameLayout { * otherwise don't. mScroller.isFinished should be false when * being flinged. */ - mIsBeingDragged = !mScroller.isFinished(); + mIsBeingDragged = !mScroller.isFinished() || !mEdgeGlowLeft.isFinished() + || !mEdgeGlowRight.isFinished(); + // Catch the edge effect if it is active. + if (!mEdgeGlowLeft.isFinished()) { + mEdgeGlowLeft.onPullDistance(0f, 1f - ev.getY() / getHeight()); + } + if (!mEdgeGlowRight.isFinished()) { + mEdgeGlowRight.onPullDistance(0f, ev.getY() / getHeight()); + } break; } @@ -675,7 +685,8 @@ public class HorizontalScrollView extends FrameLayout { if (getChildCount() == 0) { return false; } - if ((mIsBeingDragged = !mScroller.isFinished())) { + if ((mIsBeingDragged = !mScroller.isFinished() || !mEdgeGlowRight.isFinished() + || !mEdgeGlowLeft.isFinished())) { final ViewParent parent = getParent(); if (parent != null) { parent.requestDisallowInterceptTouchEvent(true); @@ -721,12 +732,26 @@ public class HorizontalScrollView extends FrameLayout { mLastMotionX = x; final int oldX = mScrollX; - final int oldY = mScrollY; final int range = getScrollRange(); final int overscrollMode = getOverScrollMode(); final boolean canOverscroll = overscrollMode == OVER_SCROLL_ALWAYS || (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0); + final float displacement = ev.getY(activePointerIndex) / getHeight(); + if (canOverscroll) { + int consumed = 0; + if (deltaX < 0 && mEdgeGlowRight.getDistance() != 0f) { + consumed = Math.round(getHeight() + * mEdgeGlowRight.onPullDistance((float) deltaX / getWidth(), + displacement)); + } else if (deltaX > 0 && mEdgeGlowLeft.getDistance() != 0f) { + consumed = Math.round(-getHeight() + * mEdgeGlowLeft.onPullDistance((float) -deltaX / getWidth(), + 1 - displacement)); + } + deltaX -= consumed; + } + // Calling overScrollBy will call onOverScrolled, which // calls onScrollChanged if applicable. if (overScrollBy(deltaX, 0, mScrollX, 0, range, 0, @@ -735,17 +760,17 @@ public class HorizontalScrollView extends FrameLayout { mVelocityTracker.clear(); } - if (canOverscroll) { + if (canOverscroll && deltaX != 0f) { final int pulledToX = oldX + deltaX; if (pulledToX < 0) { - mEdgeGlowLeft.onPull((float) deltaX / getWidth(), - 1.f - ev.getY(activePointerIndex) / getHeight()); + mEdgeGlowLeft.onPullDistance((float) -deltaX / getWidth(), + 1.f - displacement); if (!mEdgeGlowRight.isFinished()) { mEdgeGlowRight.onRelease(); } } else if (pulledToX > range) { - mEdgeGlowRight.onPull((float) deltaX / getWidth(), - ev.getY(activePointerIndex) / getHeight()); + mEdgeGlowRight.onPullDistance((float) deltaX / getWidth(), + displacement); if (!mEdgeGlowLeft.isFinished()) { mEdgeGlowLeft.onRelease(); } diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java index f3de9828c4aa..64d09de49f2d 100644 --- a/core/java/android/widget/ScrollView.java +++ b/core/java/android/widget/ScrollView.java @@ -98,7 +98,7 @@ public class ScrollView extends FrameLayout { */ @NonNull @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768600) - private EdgeEffect mEdgeGlowTop = new EdgeEffect(getContext()); + private EdgeEffect mEdgeGlowTop; /** * Tracks the state of the bottom edge glow. @@ -108,7 +108,7 @@ public class ScrollView extends FrameLayout { */ @NonNull @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769386) - private EdgeEffect mEdgeGlowBottom = new EdgeEffect(getContext()); + private EdgeEffect mEdgeGlowBottom; /** * Position of the last motion event. @@ -213,6 +213,8 @@ public class ScrollView extends FrameLayout { public ScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); + mEdgeGlowTop = new EdgeEffect(context, attrs); + mEdgeGlowBottom = new EdgeEffect(context, attrs); initScrollView(); final TypedArray a = context.obtainStyledAttributes( @@ -679,7 +681,15 @@ public class ScrollView extends FrameLayout { * isFinished() is correct. */ mScroller.computeScrollOffset(); - mIsBeingDragged = !mScroller.isFinished(); + mIsBeingDragged = !mScroller.isFinished() || !mEdgeGlowBottom.isFinished() + || !mEdgeGlowTop.isFinished(); + // Catch the edge effect if it is active. + if (!mEdgeGlowTop.isFinished()) { + mEdgeGlowTop.onPullDistance(0f, ev.getX() / getWidth()); + } + if (!mEdgeGlowBottom.isFinished()) { + mEdgeGlowBottom.onPullDistance(0f, 1f - ev.getX() / getWidth()); + } if (mIsBeingDragged && mScrollStrictSpan == null) { mScrollStrictSpan = StrictMode.enterCriticalSpan("ScrollView-scroll"); } @@ -732,7 +742,8 @@ public class ScrollView extends FrameLayout { if (getChildCount() == 0) { return false; } - if ((mIsBeingDragged = !mScroller.isFinished())) { + if ((mIsBeingDragged = !mScroller.isFinished() || !mEdgeGlowTop.isFinished() + || !mEdgeGlowBottom.isFinished())) { final ViewParent parent = getParent(); if (parent != null) { parent.requestDisallowInterceptTouchEvent(true); @@ -793,6 +804,21 @@ public class ScrollView extends FrameLayout { boolean canOverscroll = overscrollMode == OVER_SCROLL_ALWAYS || (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0); + final float displacement = ev.getX(activePointerIndex) / getWidth(); + if (canOverscroll) { + int consumed = 0; + if (deltaY < 0 && mEdgeGlowBottom.getDistance() != 0f) { + consumed = Math.round(getHeight() + * mEdgeGlowBottom.onPullDistance((float) deltaY / getHeight(), + 1 - displacement)); + } else if (deltaY > 0 && mEdgeGlowTop.getDistance() != 0f) { + consumed = Math.round(-getHeight() + * mEdgeGlowTop.onPullDistance((float) -deltaY / getHeight(), + displacement)); + } + deltaY -= consumed; + } + // Calling overScrollBy will call onOverScrolled, which // calls onScrollChanged if applicable. if (overScrollBy(0, deltaY, 0, mScrollY, 0, range, 0, mOverscrollDistance, true) @@ -807,17 +833,17 @@ public class ScrollView extends FrameLayout { mLastMotionY -= mScrollOffset[1]; vtev.offsetLocation(0, mScrollOffset[1]); mNestedYOffset += mScrollOffset[1]; - } else if (canOverscroll) { + } else if (canOverscroll && deltaY != 0f) { final int pulledToY = oldY + deltaY; if (pulledToY < 0) { - mEdgeGlowTop.onPull((float) deltaY / getHeight(), - ev.getX(activePointerIndex) / getWidth()); + mEdgeGlowTop.onPullDistance((float) -deltaY / getHeight(), + displacement); if (!mEdgeGlowBottom.isFinished()) { mEdgeGlowBottom.onRelease(); } } else if (pulledToY > range) { - mEdgeGlowBottom.onPull((float) deltaY / getHeight(), - 1.f - ev.getX(activePointerIndex) / getWidth()); + mEdgeGlowBottom.onPullDistance((float) deltaY / getHeight(), + 1.f - displacement); if (!mEdgeGlowTop.isFinished()) { mEdgeGlowTop.onRelease(); } |