From c9fbaabc1bbf847b6e8bf2595068cbd990f3da55 Mon Sep 17 00:00:00 2001 From: Adam Powell Date: Tue, 16 Feb 2010 17:16:19 -0800 Subject: [PATCH] XML attribute for overscrolling behavior --- api/current.xml | 11 +++ core/java/android/view/View.java | 114 +++++++++++++++------- core/java/android/widget/AbsListView.java | 3 +- core/res/res/values/attrs.xml | 13 +++ core/res/res/values/public.xml | 1 + 5 files changed, 106 insertions(+), 36 deletions(-) diff --git a/api/current.xml b/api/current.xml index 5e4839567623c..eb1c6d61e9f72 100644 --- a/api/current.xml +++ b/api/current.xml @@ -5960,6 +5960,17 @@ visibility="public" > + + dropoffRight && deltaX > 0)) { - newScrollX = scrollX + deltaX / 2; - } else { - newScrollX = scrollX + deltaX; - if (newScrollX > dropoffRight && deltaX > 0) { - int extra = newScrollX - dropoffRight; - newScrollX = dropoffRight + extra / 2; - } else if (newScrollX < dropoffLeft && deltaX < 0) { - int extra = newScrollX - dropoffLeft; - newScrollX = dropoffLeft + extra / 2; - } - } + final int overscrollMode = mOverscrollMode; + final boolean canScrollHorizontal = + computeHorizontalScrollRange() > computeHorizontalScrollExtent(); + final boolean canScrollVertical = + computeVerticalScrollRange() > computeVerticalScrollExtent(); + final boolean overscrollHorizontal = overscrollMode == OVERSCROLL_ALWAYS || + (overscrollMode == OVERSCROLL_IF_CONTENT_SCROLLS && canScrollHorizontal); + final boolean overscrollVertical = overscrollMode == OVERSCROLL_ALWAYS || + (overscrollMode == OVERSCROLL_IF_CONTENT_SCROLLS && canScrollVertical); - final int dropoffY = maxOverscrollY / 2; - final int dropoffTop = -dropoffY; - final int dropoffBottom = dropoffY + scrollRangeY; - int newScrollY; - if ((scrollY < dropoffTop && deltaY < 0) || - (scrollY > dropoffBottom && deltaY > 0)) { - newScrollY = scrollY + deltaY / 2; - } else { - newScrollY = scrollY + deltaY; - if (newScrollY > dropoffBottom && deltaY > 0) { - int extra = newScrollY - dropoffBottom; - newScrollY = dropoffBottom + extra / 2; - } else if (newScrollY < dropoffTop && deltaY < 0) { - int extra = newScrollY - dropoffTop; - newScrollY = dropoffTop + extra / 2; + int newScrollX = scrollX + deltaX; + if (overscrollHorizontal) { + // Scale the scroll amount if we're in the dropoff zone + final int dropoffX = maxOverscrollX / 2; + final int dropoffLeft = -dropoffX; + final int dropoffRight = dropoffX + scrollRangeX; + if ((scrollX < dropoffLeft && deltaX < 0) || + (scrollX > dropoffRight && deltaX > 0)) { + newScrollX = scrollX + deltaX / 2; + } else { + if (newScrollX > dropoffRight && deltaX > 0) { + int extra = newScrollX - dropoffRight; + newScrollX = dropoffRight + extra / 2; + } else if (newScrollX < dropoffLeft && deltaX < 0) { + int extra = newScrollX - dropoffLeft; + newScrollX = dropoffLeft + extra / 2; + } } + } else { + maxOverscrollX = 0; } + int newScrollY = scrollY + deltaY; + if (overscrollVertical) { + final int dropoffY = maxOverscrollY / 2; + final int dropoffTop = -dropoffY; + final int dropoffBottom = dropoffY + scrollRangeY; + if ((scrollY < dropoffTop && deltaY < 0) || + (scrollY > dropoffBottom && deltaY > 0)) { + newScrollY = scrollY + deltaY / 2; + } else { + if (newScrollY > dropoffBottom && deltaY > 0) { + int extra = newScrollY - dropoffBottom; + newScrollY = dropoffBottom + extra / 2; + } else if (newScrollY < dropoffTop && deltaY < 0) { + int extra = newScrollY - dropoffTop; + newScrollY = dropoffTop + extra / 2; + } + } + } else { + maxOverscrollY = 0; + } + // Clamp values if at the limits and record final int left = -maxOverscrollX; final int right = maxOverscrollX + scrollRangeX; @@ -8636,8 +8680,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility // Bump the device with some haptic feedback if we're at the edge // and didn't start there. - if ((clampedX && scrollX != left && scrollX != right) || - (clampedY && scrollY != top && scrollY != bottom)) { + if ((overscrollHorizontal && clampedX && scrollX != left && scrollX != right) || + (overscrollVertical && clampedY && scrollY != top && scrollY != bottom)) { performHapticFeedback(HapticFeedbackConstants.SCROLL_BARRIER); } diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 4c77bdc928a87..254efe7921803 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -2589,7 +2589,8 @@ public abstract class AbsListView extends AdapterView implements Te if (trackMotionScroll(delta, delta)) { if (motionView != null) { // Tweak the scroll for how far we overshot - mScrollY -= delta - (motionView.getTop() - oldTop); + int overshoot = -(delta - (motionView.getTop() - oldTop)); + overscrollBy(0, overshoot, 0, mScrollY, 0, 0, 0, getOverscrollMax()); } float vel = scroller.getCurrVelocity(); if (delta > 0) { diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 0f6a5c1cb9850..ff9398417b20a 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -1307,6 +1307,19 @@ public void sayHello(View v) method of your context (typically, your Activity). --> + + + + + + + + + +