Invalidate for scrolling animations on the animation timer
Change View methods awakenScrollBars and scrollTo to post their
invalidation on the animation timer. Since these are often used in
computeScroll or similar to continue scrolling or flinging it should
not prevent other posted events from being processed before the frame
is actually drawn. (All changes in scroll position, etc. are
immediately reflected after the calls and do not need a draw to
present correct data about scroll position to apps.)
Don't accumulate floating point error while dragging
ScrollView/HorizontalScrollView.
Change-Id: I05b57d75f89a806488e46a8fb79b85d80f56d45d
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index d62e32f..c168b3e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8698,7 +8698,7 @@
invalidateParentCaches();
onScrollChanged(mScrollX, mScrollY, oldX, oldY);
if (!awakenScrollBars()) {
- invalidate(true);
+ postInvalidateOnAnimation();
}
}
}
@@ -8852,7 +8852,7 @@
if (invalidate) {
// Invalidate to show the scrollbars
- invalidate(true);
+ postInvalidateOnAnimation();
}
if (scrollCache.state == ScrollabilityCache.OFF) {
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 4e13ea1..c2559a5 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -77,7 +77,7 @@
/**
* Position of the last motion event.
*/
- private float mLastMotionX;
+ private int mLastMotionX;
/**
* True when the layout has changed but the traversal has not come through yet.
@@ -460,7 +460,7 @@
}
final int pointerIndex = ev.findPointerIndex(activePointerId);
- final float x = ev.getX(pointerIndex);
+ final int x = (int) ev.getX(pointerIndex);
final int xDiff = (int) Math.abs(x - mLastMotionX);
if (xDiff > mTouchSlop) {
mIsBeingDragged = true;
@@ -473,7 +473,7 @@
}
case MotionEvent.ACTION_DOWN: {
- final float x = ev.getX();
+ final int x = (int) ev.getX();
if (!inChild((int) x, (int) ev.getY())) {
mIsBeingDragged = false;
recycleVelocityTracker();
@@ -505,18 +505,18 @@
mIsBeingDragged = false;
mActivePointerId = INVALID_POINTER;
if (mScroller.springBack(mScrollX, mScrollY, 0, getScrollRange(), 0, 0)) {
- invalidate();
+ postInvalidateOnAnimation();
}
break;
case MotionEvent.ACTION_POINTER_DOWN: {
final int index = ev.getActionIndex();
- mLastMotionX = ev.getX(index);
+ mLastMotionX = (int) ev.getX(index);
mActivePointerId = ev.getPointerId(index);
break;
}
case MotionEvent.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
- mLastMotionX = ev.getX(ev.findPointerIndex(mActivePointerId));
+ mLastMotionX = (int) ev.getX(ev.findPointerIndex(mActivePointerId));
break;
}
@@ -550,7 +550,7 @@
}
// Remember where the motion event started
- mLastMotionX = ev.getX();
+ mLastMotionX = (int) ev.getX();
mActivePointerId = ev.getPointerId(0);
break;
}
@@ -558,7 +558,7 @@
if (mIsBeingDragged) {
// Scroll to follow the motion event
final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
- final float x = ev.getX(activePointerIndex);
+ final int x = (int) ev.getX(activePointerIndex);
final int deltaX = (int) (mLastMotionX - x);
mLastMotionX = x;
@@ -591,7 +591,7 @@
}
if (mEdgeGlowLeft != null
&& (!mEdgeGlowLeft.isFinished() || !mEdgeGlowRight.isFinished())) {
- invalidate();
+ postInvalidateOnAnimation();
}
}
}
@@ -608,7 +608,7 @@
} else {
if (mScroller.springBack(mScrollX, mScrollY, 0,
getScrollRange(), 0, 0)) {
- invalidate();
+ postInvalidateOnAnimation();
}
}
}
@@ -626,7 +626,7 @@
case MotionEvent.ACTION_CANCEL:
if (mIsBeingDragged && getChildCount() > 0) {
if (mScroller.springBack(mScrollX, mScrollY, 0, getScrollRange(), 0, 0)) {
- invalidate();
+ postInvalidateOnAnimation();
}
mActivePointerId = INVALID_POINTER;
mIsBeingDragged = false;
@@ -654,7 +654,7 @@
// active pointer and adjust accordingly.
// TODO: Make this decision more intelligent.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
- mLastMotionX = ev.getX(newPointerIndex);
+ mLastMotionX = (int) ev.getX(newPointerIndex);
mActivePointerId = ev.getPointerId(newPointerIndex);
if (mVelocityTracker != null) {
mVelocityTracker.clear();
@@ -1084,7 +1084,7 @@
dx = Math.max(0, Math.min(scrollX + dx, maxX)) - scrollX;
mScroller.startScroll(scrollX, mScrollY, dx, 0);
- invalidate();
+ postInvalidateOnAnimation();
} else {
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
@@ -1206,7 +1206,7 @@
}
if (!awakenScrollBars()) {
- invalidate();
+ postInvalidateOnAnimation();
}
}
}
@@ -1452,7 +1452,7 @@
newFocused.requestFocus(movingRight ? View.FOCUS_RIGHT : View.FOCUS_LEFT);
}
- invalidate();
+ postInvalidateOnAnimation();
}
}
@@ -1503,7 +1503,7 @@
canvas.translate(-height + mPaddingTop, Math.min(0, scrollX));
mEdgeGlowLeft.setSize(height, getWidth());
if (mEdgeGlowLeft.draw(canvas)) {
- invalidate();
+ postInvalidateOnAnimation();
}
canvas.restoreToCount(restoreCount);
}
@@ -1517,7 +1517,7 @@
-(Math.max(getScrollRange(), scrollX) + width));
mEdgeGlowRight.setSize(height, width);
if (mEdgeGlowRight.draw(canvas)) {
- invalidate();
+ postInvalidateOnAnimation();
}
canvas.restoreToCount(restoreCount);
}
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index e0e3e93..0f0dbae 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -73,7 +73,7 @@
/**
* Position of the last motion event.
*/
- private float mLastMotionY;
+ private int mLastMotionY;
/**
* True when the layout has changed but the traversal has not come through yet.
@@ -472,8 +472,8 @@
}
final int pointerIndex = ev.findPointerIndex(activePointerId);
- final float y = ev.getY(pointerIndex);
- final int yDiff = (int) Math.abs(y - mLastMotionY);
+ final int y = (int) ev.getY(pointerIndex);
+ final int yDiff = Math.abs(y - mLastMotionY);
if (yDiff > mTouchSlop) {
mIsBeingDragged = true;
mLastMotionY = y;
@@ -487,7 +487,7 @@
}
case MotionEvent.ACTION_DOWN: {
- final float y = ev.getY();
+ final int y = (int) ev.getY();
if (!inChild((int) ev.getX(), (int) y)) {
mIsBeingDragged = false;
recycleVelocityTracker();
@@ -522,7 +522,7 @@
mActivePointerId = INVALID_POINTER;
recycleVelocityTracker();
if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange())) {
- invalidate();
+ postInvalidateOnAnimation();
}
break;
case MotionEvent.ACTION_POINTER_UP:
@@ -564,7 +564,7 @@
}
// Remember where the motion event started
- mLastMotionY = ev.getY();
+ mLastMotionY = (int) ev.getY();
mActivePointerId = ev.getPointerId(0);
break;
}
@@ -572,8 +572,8 @@
if (mIsBeingDragged) {
// Scroll to follow the motion event
final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
- final float y = ev.getY(activePointerIndex);
- final int deltaY = (int) (mLastMotionY - y);
+ final int y = (int) ev.getY(activePointerIndex);
+ final int deltaY = mLastMotionY - y;
mLastMotionY = y;
final int oldX = mScrollX;
@@ -605,7 +605,7 @@
}
if (mEdgeGlowTop != null
&& (!mEdgeGlowTop.isFinished() || !mEdgeGlowBottom.isFinished())) {
- invalidate();
+ postInvalidateOnAnimation();
}
}
}
@@ -622,7 +622,7 @@
} else {
if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0,
getScrollRange())) {
- invalidate();
+ postInvalidateOnAnimation();
}
}
}
@@ -634,7 +634,7 @@
case MotionEvent.ACTION_CANCEL:
if (mIsBeingDragged && getChildCount() > 0) {
if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange())) {
- invalidate();
+ postInvalidateOnAnimation();
}
mActivePointerId = INVALID_POINTER;
endDrag();
@@ -642,13 +642,13 @@
break;
case MotionEvent.ACTION_POINTER_DOWN: {
final int index = ev.getActionIndex();
- mLastMotionY = ev.getY(index);
+ mLastMotionY = (int) ev.getY(index);
mActivePointerId = ev.getPointerId(index);
break;
}
case MotionEvent.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
- mLastMotionY = ev.getY(ev.findPointerIndex(mActivePointerId));
+ mLastMotionY = (int) ev.getY(ev.findPointerIndex(mActivePointerId));
break;
}
return true;
@@ -663,7 +663,7 @@
// active pointer and adjust accordingly.
// TODO: Make this decision more intelligent.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
- mLastMotionY = ev.getY(newPointerIndex);
+ mLastMotionY = (int) ev.getY(newPointerIndex);
mActivePointerId = ev.getPointerId(newPointerIndex);
if (mVelocityTracker != null) {
mVelocityTracker.clear();
@@ -1047,7 +1047,7 @@
dy = Math.max(0, Math.min(scrollY + dy, maxY)) - scrollY;
mScroller.startScroll(mScrollX, scrollY, 0, dy);
- invalidate();
+ postInvalidateOnAnimation();
} else {
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
@@ -1174,7 +1174,7 @@
if (!awakenScrollBars()) {
// Keep on drawing until the animation has finished.
- invalidate();
+ postInvalidateOnAnimation();
}
} else {
if (mFlingStrictSpan != null) {
@@ -1430,7 +1430,7 @@
mFlingStrictSpan = StrictMode.enterCriticalSpan("ScrollView-fling");
}
- invalidate();
+ postInvalidateOnAnimation();
}
}
@@ -1495,7 +1495,7 @@
canvas.translate(mPaddingLeft, Math.min(0, scrollY));
mEdgeGlowTop.setSize(width, getHeight());
if (mEdgeGlowTop.draw(canvas)) {
- invalidate();
+ postInvalidateOnAnimation();
}
canvas.restoreToCount(restoreCount);
}
@@ -1509,7 +1509,7 @@
canvas.rotate(180, width, 0);
mEdgeGlowBottom.setSize(width, height);
if (mEdgeGlowBottom.draw(canvas)) {
- invalidate();
+ postInvalidateOnAnimation();
}
canvas.restoreToCount(restoreCount);
}