diff options
| -rw-r--r-- | api/current.xml | 11 | ||||
| -rw-r--r-- | core/java/android/view/View.java | 114 | ||||
| -rw-r--r-- | core/java/android/widget/AbsListView.java | 3 | ||||
| -rw-r--r-- | core/res/res/values/attrs.xml | 13 | ||||
| -rw-r--r-- | 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 5e4839567623..eb1c6d61e9f7 100644 --- a/api/current.xml +++ b/api/current.xml @@ -5960,6 +5960,17 @@ visibility="public" > </field> +<field name="overscrollMode" + type="int" + transient="false" + volatile="false" + value="16843450" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="padding" type="int" transient="false" diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 57fdd8b0660b..e5db12097fe5 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -1504,6 +1504,31 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility * @hide */ private static final int PREPRESSED = 0x02000000; + + /** + * Always allow a user to overscroll this view, provided it is a + * view that can scroll. + */ + private static final int OVERSCROLL_ALWAYS = 0; + + /** + * Allow a user to overscroll this view only if the content is large + * enough to meaningfully scroll, provided it is a view that can scroll. + */ + private static final int OVERSCROLL_IF_CONTENT_SCROLLS = 1; + + /** + * Never allow a user to overscroll this view. + */ + private static final int OVERSCROLL_NEVER = 2; + + /** + * Controls the overscroll mode for this view. + * See {@link #overscrollBy(int, int, int, int, int, int, int, int)}, + * {@link #OVERSCROLL_ALWAYS}, {@link #OVERSCROLL_IF_CONTENT_SCROLLS}, + * and {@link #OVERSCROLL_NEVER}. + */ + private int mOverscrollMode = OVERSCROLL_ALWAYS; /** * The parent this view is attached to. @@ -2053,6 +2078,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility }); } break; + case R.styleable.View_overscrollMode: + mOverscrollMode = a.getInt(attr, OVERSCROLL_ALWAYS); + break; } } @@ -8573,43 +8601,59 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverscrollX, int maxOverscrollY) { - // 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; - int newScrollX; - if ((scrollX < dropoffLeft && deltaX < 0) || - (scrollX > 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 4c77bdc928a8..254efe792180 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<ListAdapter> 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 0f6a5c1cb985..ff9398417b20 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -1307,6 +1307,19 @@ <code>public void sayHello(View v)</code> method of your context (typically, your Activity). --> <attr name="onClick" format="string" /> + + <!-- Defines overscrolling behavior. This property is used only if the + View is scrollable. Overscrolling is the ability for the user to + scroll a View beyond its content boundaries into empty space. --> + <attr name="overscrollMode"> + <!-- Always allow the user to overscroll the content. --> + <enum name="always" value="0" /> + <!-- Only allow the user to overscroll content if the content is large + enough to meaningfully scroll. --> + <enum name="ifContentScrolls" value="1" /> + <!-- Never overscroll. --> + <enum name="never" value="2" /> + </attr> </declare-styleable> <!-- Attributes that can be used with a {@link android.view.ViewGroup} or any diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 82c02eb50ee7..b3343375e90f 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1230,6 +1230,7 @@ <public type="attr" name="installLocation" id="0x010102b7" /> <public type="attr" name="safeMode" id="0x010102b8" /> <public type="attr" name="webTextViewStyle" id="0x010102b9" /> + <public type="attr" name="overscrollMode" id="0x010102ba" /> <public type="anim" name="cycle_interpolator" id="0x010a000c" /> |