Skip to content

Commit df3ae4f

Browse files
committed
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
1 parent 54ae147 commit df3ae4f

File tree

3 files changed

+38
-38
lines changed

3 files changed

+38
-38
lines changed

core/java/android/view/View.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8698,7 +8698,7 @@ public void scrollTo(int x, int y) {
86988698
invalidateParentCaches();
86998699
onScrollChanged(mScrollX, mScrollY, oldX, oldY);
87008700
if (!awakenScrollBars()) {
8701-
invalidate(true);
8701+
postInvalidateOnAnimation();
87028702
}
87038703
}
87048704
}
@@ -8852,7 +8852,7 @@ protected boolean awakenScrollBars(int startDelay, boolean invalidate) {
88528852

88538853
if (invalidate) {
88548854
// Invalidate to show the scrollbars
8855-
invalidate(true);
8855+
postInvalidateOnAnimation();
88568856
}
88578857

88588858
if (scrollCache.state == ScrollabilityCache.OFF) {

core/java/android/widget/HorizontalScrollView.java

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public class HorizontalScrollView extends FrameLayout {
7777
/**
7878
* Position of the last motion event.
7979
*/
80-
private float mLastMotionX;
80+
private int mLastMotionX;
8181

8282
/**
8383
* True when the layout has changed but the traversal has not come through yet.
@@ -460,7 +460,7 @@ public boolean onInterceptTouchEvent(MotionEvent ev) {
460460
}
461461

462462
final int pointerIndex = ev.findPointerIndex(activePointerId);
463-
final float x = ev.getX(pointerIndex);
463+
final int x = (int) ev.getX(pointerIndex);
464464
final int xDiff = (int) Math.abs(x - mLastMotionX);
465465
if (xDiff > mTouchSlop) {
466466
mIsBeingDragged = true;
@@ -473,7 +473,7 @@ public boolean onInterceptTouchEvent(MotionEvent ev) {
473473
}
474474

475475
case MotionEvent.ACTION_DOWN: {
476-
final float x = ev.getX();
476+
final int x = (int) ev.getX();
477477
if (!inChild((int) x, (int) ev.getY())) {
478478
mIsBeingDragged = false;
479479
recycleVelocityTracker();
@@ -505,18 +505,18 @@ public boolean onInterceptTouchEvent(MotionEvent ev) {
505505
mIsBeingDragged = false;
506506
mActivePointerId = INVALID_POINTER;
507507
if (mScroller.springBack(mScrollX, mScrollY, 0, getScrollRange(), 0, 0)) {
508-
invalidate();
508+
postInvalidateOnAnimation();
509509
}
510510
break;
511511
case MotionEvent.ACTION_POINTER_DOWN: {
512512
final int index = ev.getActionIndex();
513-
mLastMotionX = ev.getX(index);
513+
mLastMotionX = (int) ev.getX(index);
514514
mActivePointerId = ev.getPointerId(index);
515515
break;
516516
}
517517
case MotionEvent.ACTION_POINTER_UP:
518518
onSecondaryPointerUp(ev);
519-
mLastMotionX = ev.getX(ev.findPointerIndex(mActivePointerId));
519+
mLastMotionX = (int) ev.getX(ev.findPointerIndex(mActivePointerId));
520520
break;
521521
}
522522

@@ -550,15 +550,15 @@ public boolean onTouchEvent(MotionEvent ev) {
550550
}
551551

552552
// Remember where the motion event started
553-
mLastMotionX = ev.getX();
553+
mLastMotionX = (int) ev.getX();
554554
mActivePointerId = ev.getPointerId(0);
555555
break;
556556
}
557557
case MotionEvent.ACTION_MOVE:
558558
if (mIsBeingDragged) {
559559
// Scroll to follow the motion event
560560
final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
561-
final float x = ev.getX(activePointerIndex);
561+
final int x = (int) ev.getX(activePointerIndex);
562562
final int deltaX = (int) (mLastMotionX - x);
563563
mLastMotionX = x;
564564

@@ -591,7 +591,7 @@ public boolean onTouchEvent(MotionEvent ev) {
591591
}
592592
if (mEdgeGlowLeft != null
593593
&& (!mEdgeGlowLeft.isFinished() || !mEdgeGlowRight.isFinished())) {
594-
invalidate();
594+
postInvalidateOnAnimation();
595595
}
596596
}
597597
}
@@ -608,7 +608,7 @@ public boolean onTouchEvent(MotionEvent ev) {
608608
} else {
609609
if (mScroller.springBack(mScrollX, mScrollY, 0,
610610
getScrollRange(), 0, 0)) {
611-
invalidate();
611+
postInvalidateOnAnimation();
612612
}
613613
}
614614
}
@@ -626,7 +626,7 @@ public boolean onTouchEvent(MotionEvent ev) {
626626
case MotionEvent.ACTION_CANCEL:
627627
if (mIsBeingDragged && getChildCount() > 0) {
628628
if (mScroller.springBack(mScrollX, mScrollY, 0, getScrollRange(), 0, 0)) {
629-
invalidate();
629+
postInvalidateOnAnimation();
630630
}
631631
mActivePointerId = INVALID_POINTER;
632632
mIsBeingDragged = false;
@@ -654,7 +654,7 @@ private void onSecondaryPointerUp(MotionEvent ev) {
654654
// active pointer and adjust accordingly.
655655
// TODO: Make this decision more intelligent.
656656
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
657-
mLastMotionX = ev.getX(newPointerIndex);
657+
mLastMotionX = (int) ev.getX(newPointerIndex);
658658
mActivePointerId = ev.getPointerId(newPointerIndex);
659659
if (mVelocityTracker != null) {
660660
mVelocityTracker.clear();
@@ -1084,7 +1084,7 @@ public final void smoothScrollBy(int dx, int dy) {
10841084
dx = Math.max(0, Math.min(scrollX + dx, maxX)) - scrollX;
10851085

10861086
mScroller.startScroll(scrollX, mScrollY, dx, 0);
1087-
invalidate();
1087+
postInvalidateOnAnimation();
10881088
} else {
10891089
if (!mScroller.isFinished()) {
10901090
mScroller.abortAnimation();
@@ -1206,7 +1206,7 @@ public void computeScroll() {
12061206
}
12071207

12081208
if (!awakenScrollBars()) {
1209-
invalidate();
1209+
postInvalidateOnAnimation();
12101210
}
12111211
}
12121212
}
@@ -1452,7 +1452,7 @@ public void fling(int velocityX) {
14521452
newFocused.requestFocus(movingRight ? View.FOCUS_RIGHT : View.FOCUS_LEFT);
14531453
}
14541454

1455-
invalidate();
1455+
postInvalidateOnAnimation();
14561456
}
14571457
}
14581458

@@ -1503,7 +1503,7 @@ public void draw(Canvas canvas) {
15031503
canvas.translate(-height + mPaddingTop, Math.min(0, scrollX));
15041504
mEdgeGlowLeft.setSize(height, getWidth());
15051505
if (mEdgeGlowLeft.draw(canvas)) {
1506-
invalidate();
1506+
postInvalidateOnAnimation();
15071507
}
15081508
canvas.restoreToCount(restoreCount);
15091509
}
@@ -1517,7 +1517,7 @@ public void draw(Canvas canvas) {
15171517
-(Math.max(getScrollRange(), scrollX) + width));
15181518
mEdgeGlowRight.setSize(height, width);
15191519
if (mEdgeGlowRight.draw(canvas)) {
1520-
invalidate();
1520+
postInvalidateOnAnimation();
15211521
}
15221522
canvas.restoreToCount(restoreCount);
15231523
}

core/java/android/widget/ScrollView.java

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public class ScrollView extends FrameLayout {
7373
/**
7474
* Position of the last motion event.
7575
*/
76-
private float mLastMotionY;
76+
private int mLastMotionY;
7777

7878
/**
7979
* True when the layout has changed but the traversal has not come through yet.
@@ -472,8 +472,8 @@ public boolean onInterceptTouchEvent(MotionEvent ev) {
472472
}
473473

474474
final int pointerIndex = ev.findPointerIndex(activePointerId);
475-
final float y = ev.getY(pointerIndex);
476-
final int yDiff = (int) Math.abs(y - mLastMotionY);
475+
final int y = (int) ev.getY(pointerIndex);
476+
final int yDiff = Math.abs(y - mLastMotionY);
477477
if (yDiff > mTouchSlop) {
478478
mIsBeingDragged = true;
479479
mLastMotionY = y;
@@ -487,7 +487,7 @@ public boolean onInterceptTouchEvent(MotionEvent ev) {
487487
}
488488

489489
case MotionEvent.ACTION_DOWN: {
490-
final float y = ev.getY();
490+
final int y = (int) ev.getY();
491491
if (!inChild((int) ev.getX(), (int) y)) {
492492
mIsBeingDragged = false;
493493
recycleVelocityTracker();
@@ -522,7 +522,7 @@ public boolean onInterceptTouchEvent(MotionEvent ev) {
522522
mActivePointerId = INVALID_POINTER;
523523
recycleVelocityTracker();
524524
if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange())) {
525-
invalidate();
525+
postInvalidateOnAnimation();
526526
}
527527
break;
528528
case MotionEvent.ACTION_POINTER_UP:
@@ -564,16 +564,16 @@ public boolean onTouchEvent(MotionEvent ev) {
564564
}
565565

566566
// Remember where the motion event started
567-
mLastMotionY = ev.getY();
567+
mLastMotionY = (int) ev.getY();
568568
mActivePointerId = ev.getPointerId(0);
569569
break;
570570
}
571571
case MotionEvent.ACTION_MOVE:
572572
if (mIsBeingDragged) {
573573
// Scroll to follow the motion event
574574
final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
575-
final float y = ev.getY(activePointerIndex);
576-
final int deltaY = (int) (mLastMotionY - y);
575+
final int y = (int) ev.getY(activePointerIndex);
576+
final int deltaY = mLastMotionY - y;
577577
mLastMotionY = y;
578578

579579
final int oldX = mScrollX;
@@ -605,7 +605,7 @@ public boolean onTouchEvent(MotionEvent ev) {
605605
}
606606
if (mEdgeGlowTop != null
607607
&& (!mEdgeGlowTop.isFinished() || !mEdgeGlowBottom.isFinished())) {
608-
invalidate();
608+
postInvalidateOnAnimation();
609609
}
610610
}
611611
}
@@ -622,7 +622,7 @@ public boolean onTouchEvent(MotionEvent ev) {
622622
} else {
623623
if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0,
624624
getScrollRange())) {
625-
invalidate();
625+
postInvalidateOnAnimation();
626626
}
627627
}
628628
}
@@ -634,21 +634,21 @@ public boolean onTouchEvent(MotionEvent ev) {
634634
case MotionEvent.ACTION_CANCEL:
635635
if (mIsBeingDragged && getChildCount() > 0) {
636636
if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange())) {
637-
invalidate();
637+
postInvalidateOnAnimation();
638638
}
639639
mActivePointerId = INVALID_POINTER;
640640
endDrag();
641641
}
642642
break;
643643
case MotionEvent.ACTION_POINTER_DOWN: {
644644
final int index = ev.getActionIndex();
645-
mLastMotionY = ev.getY(index);
645+
mLastMotionY = (int) ev.getY(index);
646646
mActivePointerId = ev.getPointerId(index);
647647
break;
648648
}
649649
case MotionEvent.ACTION_POINTER_UP:
650650
onSecondaryPointerUp(ev);
651-
mLastMotionY = ev.getY(ev.findPointerIndex(mActivePointerId));
651+
mLastMotionY = (int) ev.getY(ev.findPointerIndex(mActivePointerId));
652652
break;
653653
}
654654
return true;
@@ -663,7 +663,7 @@ private void onSecondaryPointerUp(MotionEvent ev) {
663663
// active pointer and adjust accordingly.
664664
// TODO: Make this decision more intelligent.
665665
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
666-
mLastMotionY = ev.getY(newPointerIndex);
666+
mLastMotionY = (int) ev.getY(newPointerIndex);
667667
mActivePointerId = ev.getPointerId(newPointerIndex);
668668
if (mVelocityTracker != null) {
669669
mVelocityTracker.clear();
@@ -1047,7 +1047,7 @@ public final void smoothScrollBy(int dx, int dy) {
10471047
dy = Math.max(0, Math.min(scrollY + dy, maxY)) - scrollY;
10481048

10491049
mScroller.startScroll(mScrollX, scrollY, 0, dy);
1050-
invalidate();
1050+
postInvalidateOnAnimation();
10511051
} else {
10521052
if (!mScroller.isFinished()) {
10531053
mScroller.abortAnimation();
@@ -1174,7 +1174,7 @@ public void computeScroll() {
11741174

11751175
if (!awakenScrollBars()) {
11761176
// Keep on drawing until the animation has finished.
1177-
invalidate();
1177+
postInvalidateOnAnimation();
11781178
}
11791179
} else {
11801180
if (mFlingStrictSpan != null) {
@@ -1430,7 +1430,7 @@ public void fling(int velocityY) {
14301430
mFlingStrictSpan = StrictMode.enterCriticalSpan("ScrollView-fling");
14311431
}
14321432

1433-
invalidate();
1433+
postInvalidateOnAnimation();
14341434
}
14351435
}
14361436

@@ -1495,7 +1495,7 @@ public void draw(Canvas canvas) {
14951495
canvas.translate(mPaddingLeft, Math.min(0, scrollY));
14961496
mEdgeGlowTop.setSize(width, getHeight());
14971497
if (mEdgeGlowTop.draw(canvas)) {
1498-
invalidate();
1498+
postInvalidateOnAnimation();
14991499
}
15001500
canvas.restoreToCount(restoreCount);
15011501
}
@@ -1509,7 +1509,7 @@ public void draw(Canvas canvas) {
15091509
canvas.rotate(180, width, 0);
15101510
mEdgeGlowBottom.setSize(width, height);
15111511
if (mEdgeGlowBottom.draw(canvas)) {
1512-
invalidate();
1512+
postInvalidateOnAnimation();
15131513
}
15141514
canvas.restoreToCount(restoreCount);
15151515
}

0 commit comments

Comments
 (0)