ScrollView and HorizontalScrollView now will spring back if smoothScrollBy scrolls out of bounds. Tweaked bounce physics for OverScroller.
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 4cc3b9e..8c39231 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -815,9 +815,16 @@
* @param dy the number of pixels to scroll by on the Y axis
*/
public final void smoothScrollBy(int dx, int dy) {
+ if (getChildCount() == 0) {
+ // Nothing to do.
+ return;
+ }
long duration = AnimationUtils.currentAnimationTimeMillis() - mLastScroll;
if (duration > ANIMATED_SCROLL_GAP) {
- mScroller.startScroll(mScrollX, mScrollY, dx, dy);
+ int width = getWidth() - mPaddingRight - mPaddingLeft;
+ int right = getChildAt(0).getWidth();
+ mScroller.startScroll(mScrollX, mScrollY, dx, dy,
+ 0, Math.max(0, right - width), 0, 0);
awakenScrollBars(mScroller.getDuration());
invalidate();
} else {
diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java
index 3fd5dcc..b22ae3c 100644
--- a/core/java/android/widget/OverScroller.java
+++ b/core/java/android/widget/OverScroller.java
@@ -49,7 +49,7 @@
public OverScroller(Context context) {
mDefaultScroller = new Scroller(context);
- mDecelScroller = new Scroller(context, new DecelerateInterpolator(3.f));
+ mDecelScroller = new Scroller(context, new DecelerateInterpolator());
mAccelDecelScroller = new Scroller(context, new AccelerateDecelerateInterpolator());
mCurrScroller = mDefaultScroller;
}
@@ -216,7 +216,7 @@
/**
* Start scrolling by providing a starting point and the distance to travel.
* The scroll will use the default value of 250 milliseconds for the
- * duration.
+ * duration. This version does not spring back to boundaries.
*
* @param startX Starting horizontal scroll offset in pixels. Positive
* numbers will scroll the content to the left.
@@ -228,13 +228,45 @@
* content up.
*/
public void startScroll(int startX, int startY, int dx, int dy) {
+ final int minX = Math.min(startX, startX + dx);
+ final int maxX = Math.max(startX, startX + dx);
+ final int minY = Math.min(startY, startY + dy);
+ final int maxY = Math.max(startY, startY + dy);
+ startScroll(startX, startY, dx, dy, minX, maxX, minY, maxY);
+ }
+
+ /**
+ * Start scrolling by providing a starting point and the distance to travel.
+ * The scroll will use the default value of 250 milliseconds for the
+ * duration. This version will spring back to the provided boundaries if
+ * the scroll value would take it too far.
+ *
+ * @param startX Starting horizontal scroll offset in pixels. Positive
+ * numbers will scroll the content to the left.
+ * @param startY Starting vertical scroll offset in pixels. Positive numbers
+ * will scroll the content up.
+ * @param dx Horizontal distance to travel. Positive numbers will scroll the
+ * content to the left.
+ * @param dy Vertical distance to travel. Positive numbers will scroll the
+ * content up.
+ * @param minX Minimum X value. The scroller will not scroll past this
+ * point.
+ * @param maxX Maximum X value. The scroller will not scroll past this
+ * point.
+ * @param minY Minimum Y value. The scroller will not scroll past this
+ * point.
+ * @param maxY Maximum Y value. The scroller will not scroll past this
+ * point.
+ */
+ public void startScroll(int startX, int startY, int dx, int dy,
+ int minX, int maxX, int minY, int maxY) {
mCurrScroller.abortAnimation();
mCurrScroller = mDefaultScroller;
mScrollMode = MODE_DEFAULT;
- mMinimumX = Math.min(startX, startX + dx);
- mMinimumY = Math.min(startY, startY + dy);
- mMaximumX = Math.max(startX, startX + dx);
- mMaximumY = Math.max(startY, startY + dy);
+ mMinimumX = minX;
+ mMaximumX = maxX;
+ mMinimumY = minY;
+ mMaximumY = maxY;
mCurrScroller.startScroll(startX, startY, dx, dy);
}
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 62797f3..1a50f85 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -817,9 +817,16 @@
* @param dy the number of pixels to scroll by on the Y axis
*/
public final void smoothScrollBy(int dx, int dy) {
+ if (getChildCount() == 0) {
+ // Nothing to do.
+ return;
+ }
long duration = AnimationUtils.currentAnimationTimeMillis() - mLastScroll;
if (duration > ANIMATED_SCROLL_GAP) {
- mScroller.startScroll(mScrollX, mScrollY, dx, dy);
+ int height = getHeight() - mPaddingBottom - mPaddingTop;
+ int bottom = getChildAt(0).getHeight();
+ mScroller.startScroll(mScrollX, mScrollY, dx, dy,
+ 0, 0, 0, Math.max(0, bottom - height));
awakenScrollBars(mScroller.getDuration());
invalidate();
} else {