From e9dbef85d36ce4030dae29af0d80db8d6fd0b972 Mon Sep 17 00:00:00 2001 From: Fabrice Di Meglio Date: Mon, 12 Sep 2011 16:36:46 -0700 Subject: [PATCH] Fix bug #5282141 ScrollView overscroll should not generate invalidations when not needed (ANR textview redraws constantly when touched) - check if the overscroll range is not 0 - check if we are in the correct overscroll mode - also udpate HorizontalScrollView the same way Change-Id: I0bb37f9813a5871eb856914786db5c06de59e4d3 --- .../android/widget/HorizontalScrollView.java | 35 +++++++++++-------- core/java/android/widget/ScrollView.java | 35 +++++++++++-------- 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java index a7a05be792e98..9ce8fe0775821 100644 --- a/core/java/android/widget/HorizontalScrollView.java +++ b/core/java/android/widget/HorizontalScrollView.java @@ -16,14 +16,10 @@ package android.widget; -import com.android.internal.R; - import android.content.Context; -import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Rect; -import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.FocusFinder; import android.view.InputDevice; @@ -569,16 +565,18 @@ public class HorizontalScrollView extends FrameLayout { final int oldX = mScrollX; final int oldY = mScrollY; final int range = getScrollRange(); - if (overScrollBy(deltaX, 0, mScrollX, 0, range, 0, + final int overscrollMode = getOverScrollMode(); + final boolean canOverscroll = overscrollMode == OVER_SCROLL_ALWAYS || + (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0); + + if (canOverscroll && overScrollBy(deltaX, 0, mScrollX, 0, range, 0, mOverscrollDistance, 0, true)) { // Break our velocity if we hit a scroll barrier. mVelocityTracker.clear(); } onScrollChanged(mScrollX, mScrollY, oldX, oldY); - final int overscrollMode = getOverScrollMode(); - if (overscrollMode == OVER_SCROLL_ALWAYS || - (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0)) { + if (canOverscroll) { final int pulledToX = oldX + deltaX; if (pulledToX < 0) { mEdgeGlowLeft.onPull((float) deltaX / getWidth()); @@ -604,11 +602,15 @@ public class HorizontalScrollView extends FrameLayout { velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); int initialVelocity = (int) velocityTracker.getXVelocity(mActivePointerId); - if (getChildCount() > 0) { + final int right = getScrollRange(); + final int overscrollMode = getOverScrollMode(); + final boolean canOverscroll = overscrollMode == OVER_SCROLL_ALWAYS || + (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && right > 0); + + if (getChildCount() > 0 && canOverscroll) { if ((Math.abs(initialVelocity) > mMinimumVelocity)) { fling(-initialVelocity); } else { - final int right = getScrollRange(); if (mScroller.springBack(mScrollX, mScrollY, 0, right, 0, 0)) { invalidate(); } @@ -1187,14 +1189,16 @@ public class HorizontalScrollView extends FrameLayout { int y = mScroller.getCurrY(); if (oldX != x || oldY != y) { - overScrollBy(x - oldX, y - oldY, oldX, oldY, getScrollRange(), 0, + final int range = getScrollRange(); + final int overscrollMode = getOverScrollMode(); + final boolean canOverscroll = overscrollMode == OVER_SCROLL_ALWAYS || + (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0); + + overScrollBy(x - oldX, y - oldY, oldX, oldY, range, 0, mOverflingDistance, 0, false); onScrollChanged(mScrollX, mScrollY, oldX, oldY); - final int range = getScrollRange(); - final int overscrollMode = getOverScrollMode(); - if (overscrollMode == OVER_SCROLL_ALWAYS || - (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0)) { + if (canOverscroll) { if (x < 0 && oldX >= 0) { mEdgeGlowLeft.onAbsorb((int) mScroller.getCurrVelocity()); } else if (x > range && oldX <= range) { @@ -1202,6 +1206,7 @@ public class HorizontalScrollView extends FrameLayout { } } } + awakenScrollBars(); // Keep on drawing until the animation has finished. diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java index 6a6bc236a84ae..d91eeb2d7d81a 100644 --- a/core/java/android/widget/ScrollView.java +++ b/core/java/android/widget/ScrollView.java @@ -19,11 +19,9 @@ package android.widget; import com.android.internal.R; import android.content.Context; -import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Rect; -import android.graphics.drawable.Drawable; import android.os.StrictMode; import android.util.AttributeSet; import android.view.FocusFinder; @@ -581,16 +579,18 @@ public class ScrollView extends FrameLayout { final int oldX = mScrollX; final int oldY = mScrollY; final int range = getScrollRange(); - if (overScrollBy(0, deltaY, 0, mScrollY, 0, range, - 0, mOverscrollDistance, true)) { + final int overscrollMode = getOverScrollMode(); + final boolean canOverscroll = overscrollMode == OVER_SCROLL_ALWAYS || + (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0); + + if (canOverscroll && overScrollBy(0, deltaY, 0, mScrollY, + 0, range, 0, mOverscrollDistance, true)) { // Break our velocity if we hit a scroll barrier. mVelocityTracker.clear(); } onScrollChanged(mScrollX, mScrollY, oldX, oldY); - final int overscrollMode = getOverScrollMode(); - if (overscrollMode == OVER_SCROLL_ALWAYS || - (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0)) { + if (canOverscroll) { final int pulledToY = oldY + deltaY; if (pulledToY < 0) { mEdgeGlowTop.onPull((float) deltaY / getHeight()); @@ -616,11 +616,15 @@ public class ScrollView extends FrameLayout { velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId); - if (getChildCount() > 0) { + final int bottom = getScrollRange(); + final int overscrollMode = getOverScrollMode(); + final boolean canOverscroll = overscrollMode == OVER_SCROLL_ALWAYS || + (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && bottom > 0); + + if (getChildCount() > 0 && canOverscroll) { if ((Math.abs(initialVelocity) > mMinimumVelocity)) { fling(-initialVelocity); } else { - final int bottom = getScrollRange(); if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, bottom)) { invalidate(); } @@ -1193,14 +1197,16 @@ public class ScrollView extends FrameLayout { int y = mScroller.getCurrY(); if (oldX != x || oldY != y) { - overScrollBy(x - oldX, y - oldY, oldX, oldY, 0, getScrollRange(), + final int range = getScrollRange(); + final int overscrollMode = getOverScrollMode(); + final boolean canOverscroll = overscrollMode == OVER_SCROLL_ALWAYS || + (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0); + + overScrollBy(x - oldX, y - oldY, oldX, oldY, 0, range, 0, mOverflingDistance, false); onScrollChanged(mScrollX, mScrollY, oldX, oldY); - final int range = getScrollRange(); - final int overscrollMode = getOverScrollMode(); - if (overscrollMode == OVER_SCROLL_ALWAYS || - (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0)) { + if (canOverscroll) { if (y < 0 && oldY >= 0) { mEdgeGlowTop.onAbsorb((int) mScroller.getCurrVelocity()); } else if (y > range && oldY <= range) { @@ -1208,6 +1214,7 @@ public class ScrollView extends FrameLayout { } } } + awakenScrollBars(); // Keep on drawing until the animation has finished.