diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 1d8e9a36fb3f1..588ff52d23e63 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -4363,8 +4363,35 @@ public abstract class AbsListView extends AdapterView implements Te final int delta = Math.round(axisValue * mVerticalScrollFactor); if (delta != 0) { + // If we're moving down, we want the top item. If we're moving up, bottom item. + final int motionIndex = delta > 0 ? 0 : getChildCount() - 1; + + int motionViewPrevTop = 0; + View motionView = this.getChildAt(motionIndex); + if (motionView != null) { + motionViewPrevTop = motionView.getTop(); + } + + final int overscrollMode = getOverScrollMode(); + if (!trackMotionScroll(delta, delta)) { return true; + } else if (!event.isFromSource(InputDevice.SOURCE_MOUSE) && motionView != null + && (overscrollMode == OVER_SCROLL_ALWAYS + || (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS + && !contentFits()))) { + int motionViewRealTop = motionView.getTop(); + float overscroll = (delta - (motionViewRealTop - motionViewPrevTop)) + / ((float) getHeight()); + if (delta > 0) { + mEdgeGlowTop.onPullDistance(overscroll, 0.5f); + mEdgeGlowTop.onRelease(); + } else { + mEdgeGlowBottom.onPullDistance(-overscroll, 0.5f); + mEdgeGlowBottom.onRelease(); + } + invalidate(); + return true; } } break; diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java index 018cba7f95e5c..2dbfd7e5b2e26 100644 --- a/core/java/android/widget/HorizontalScrollView.java +++ b/core/java/android/widget/HorizontalScrollView.java @@ -872,15 +872,39 @@ public class HorizontalScrollView extends FrameLayout { final int range = getScrollRange(); int oldScrollX = mScrollX; int newScrollX = oldScrollX + delta; + + final int overscrollMode = getOverScrollMode(); + boolean canOverscroll = !event.isFromSource(InputDevice.SOURCE_MOUSE) + && (overscrollMode == OVER_SCROLL_ALWAYS + || (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0)); + boolean absorbed = false; + if (newScrollX < 0) { + if (canOverscroll) { + mEdgeGlowLeft.onPullDistance(-(float) newScrollX / getWidth(), + 0.5f); + mEdgeGlowLeft.onRelease(); + invalidate(); + absorbed = true; + } newScrollX = 0; } else if (newScrollX > range) { + if (canOverscroll) { + mEdgeGlowRight.onPullDistance( + (float) (newScrollX - range) / getWidth(), 0.5f); + mEdgeGlowRight.onRelease(); + invalidate(); + absorbed = true; + } newScrollX = range; } if (newScrollX != oldScrollX) { super.scrollTo(newScrollX, mScrollY); return true; } + if (absorbed) { + return true; + } } } } diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java index 15cd17b20f4f0..2acd50c9e169b 100644 --- a/core/java/android/widget/ScrollView.java +++ b/core/java/android/widget/ScrollView.java @@ -939,15 +939,38 @@ public class ScrollView extends FrameLayout { final int range = getScrollRange(); int oldScrollY = mScrollY; int newScrollY = oldScrollY - delta; + + final int overscrollMode = getOverScrollMode(); + boolean canOverscroll = !event.isFromSource(InputDevice.SOURCE_MOUSE) + && (overscrollMode == OVER_SCROLL_ALWAYS + || (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0)); + boolean absorbed = false; + if (newScrollY < 0) { + if (canOverscroll) { + mEdgeGlowTop.onPullDistance(-(float) newScrollY / getHeight(), 0.5f); + mEdgeGlowTop.onRelease(); + invalidate(); + absorbed = true; + } newScrollY = 0; } else if (newScrollY > range) { + if (canOverscroll) { + mEdgeGlowBottom.onPullDistance( + (float) (newScrollY - range) / getHeight(), 0.5f); + mEdgeGlowBottom.onRelease(); + invalidate(); + absorbed = true; + } newScrollY = range; } if (newScrollY != oldScrollY) { super.scrollTo(mScrollX, newScrollY); return true; } + if (absorbed) { + return true; + } } break; }