@@ -88,6 +88,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
8888 ViewTreeObserver .OnTouchModeChangeListener ,
8989 RemoteViewsAdapter .RemoteAdapterConnectionCallback {
9090
91+ @ SuppressWarnings ("UnusedDeclaration" )
9192 private static final String TAG = "AbsListView" ;
9293
9394 /**
@@ -2429,7 +2430,7 @@ protected void onDetachedFromWindow() {
24292430 final ViewTreeObserver treeObserver = getViewTreeObserver ();
24302431 treeObserver .removeOnTouchModeChangeListener (this );
24312432 if (mTextFilterEnabled && mPopup != null ) {
2432- treeObserver .removeGlobalOnLayoutListener (this );
2433+ treeObserver .removeOnGlobalLayoutListener (this );
24332434 mGlobalLayoutListenerAddedFilter = false ;
24342435 }
24352436
@@ -2943,11 +2944,23 @@ private void scrollIfNeeded(int y) {
29432944 mDirection = 0 ; // Reset when entering overscroll.
29442945 mTouchMode = TOUCH_MODE_OVERSCROLL ;
29452946 if (rawDeltaY > 0 ) {
2947+ if (!mEdgeGlowTop .isIdle ()) {
2948+ invalidate (mEdgeGlowTop .getBounds ());
2949+ } else {
2950+ invalidate ();
2951+ }
2952+
29462953 mEdgeGlowTop .onPull ((float ) overscroll / getHeight ());
29472954 if (!mEdgeGlowBottom .isFinished ()) {
29482955 mEdgeGlowBottom .onRelease ();
29492956 }
29502957 } else if (rawDeltaY < 0 ) {
2958+ if (!mEdgeGlowBottom .isIdle ()) {
2959+ invalidate (mEdgeGlowBottom .getBounds ());
2960+ } else {
2961+ invalidate ();
2962+ }
2963+
29512964 mEdgeGlowBottom .onPull ((float ) overscroll / getHeight ());
29522965 if (!mEdgeGlowTop .isFinished ()) {
29532966 mEdgeGlowTop .onRelease ();
@@ -2956,7 +2969,6 @@ private void scrollIfNeeded(int y) {
29562969 }
29572970 }
29582971 mMotionY = y ;
2959- invalidate ();
29602972 }
29612973 mLastY = y ;
29622974 }
@@ -2990,26 +3002,26 @@ private void scrollIfNeeded(int y) {
29903002 if (!mEdgeGlowBottom .isFinished ()) {
29913003 mEdgeGlowBottom .onRelease ();
29923004 }
3005+ invalidate (mEdgeGlowTop .getBounds ());
29933006 } else if (rawDeltaY < 0 ) {
29943007 mEdgeGlowBottom .onPull ((float ) overScrollDistance / getHeight ());
29953008 if (!mEdgeGlowTop .isFinished ()) {
29963009 mEdgeGlowTop .onRelease ();
29973010 }
3011+ invalidate (mEdgeGlowBottom .getBounds ());
29983012 }
2999- invalidate ();
30003013 }
30013014 }
30023015
30033016 if (incrementalDeltaY != 0 ) {
30043017 // Coming back to 'real' list scrolling
3005- mScrollY = 0 ;
3006- invalidateParentIfNeeded ();
3007-
3008- // No need to do all this work if we're not going to move anyway
3009- if (incrementalDeltaY != 0 ) {
3010- trackMotionScroll (incrementalDeltaY , incrementalDeltaY );
3018+ if (mScrollY != 0 ) {
3019+ mScrollY = 0 ;
3020+ invalidateParentIfNeeded ();
30113021 }
30123022
3023+ trackMotionScroll (incrementalDeltaY , incrementalDeltaY );
3024+
30133025 mTouchMode = TOUCH_MODE_SCROLL ;
30143026
30153027 // We did not scroll the full amount. Treat this essentially like the
@@ -3468,11 +3480,12 @@ public void draw(Canvas canvas) {
34683480 final int rightPadding = mListPadding .right + mGlowPaddingRight ;
34693481 final int width = getWidth () - leftPadding - rightPadding ;
34703482
3471- canvas . translate ( leftPadding ,
3472- Math . min ( 0 , scrollY + mFirstPositionDistanceGuess ) );
3483+ int edgeY = Math . min ( 0 , scrollY + mFirstPositionDistanceGuess );
3484+ canvas . translate ( leftPadding , edgeY );
34733485 mEdgeGlowTop .setSize (width , getHeight ());
34743486 if (mEdgeGlowTop .draw (canvas )) {
3475- invalidate ();
3487+ mEdgeGlowTop .setPosition (leftPadding , edgeY );
3488+ invalidate (mEdgeGlowTop .getBounds ());
34763489 }
34773490 canvas .restoreToCount (restoreCount );
34783491 }
@@ -3483,12 +3496,15 @@ public void draw(Canvas canvas) {
34833496 final int width = getWidth () - leftPadding - rightPadding ;
34843497 final int height = getHeight ();
34853498
3486- canvas .translate (-width + leftPadding ,
3487- Math .max (height , scrollY + mLastPositionDistanceGuess ));
3499+ int edgeX = -width + leftPadding ;
3500+ int edgeY = Math .max (height , scrollY + mLastPositionDistanceGuess );
3501+ canvas .translate (edgeX , edgeY );
34883502 canvas .rotate (180 , width , 0 );
34893503 mEdgeGlowBottom .setSize (width , height );
34903504 if (mEdgeGlowBottom .draw (canvas )) {
3491- invalidate ();
3505+ // Account for the rotation
3506+ mEdgeGlowBottom .setPosition (edgeX + width , edgeY - mEdgeGlowBottom .getHeight ());
3507+ invalidate (mEdgeGlowBottom .getBounds ());
34923508 }
34933509 canvas .restoreToCount (restoreCount );
34943510 }
@@ -3874,7 +3890,8 @@ public void run() {
38743890 }
38753891
38763892 // Don't stop just because delta is zero (it could have been rounded)
3877- final boolean atEnd = trackMotionScroll (delta , delta ) && (delta != 0 );
3893+ final boolean atEdge = trackMotionScroll (delta , delta );
3894+ final boolean atEnd = atEdge && (delta != 0 );
38783895 if (atEnd ) {
38793896 if (motionView != null ) {
38803897 // Tweak the scroll for how far we overshot
@@ -3889,7 +3906,7 @@ public void run() {
38893906 }
38903907
38913908 if (more && !atEnd ) {
3892- invalidate ();
3909+ if ( atEdge ) invalidate ();
38933910 mLastFlingY = y ;
38943911 post (this );
38953912 } else {
@@ -4431,31 +4448,33 @@ void smoothScrollByOffset(int position) {
44314448 }
44324449
44334450 private void createScrollingCache () {
4434- if (mScrollingCacheEnabled && !mCachingStarted ) {
4451+ if (mScrollingCacheEnabled && !mCachingStarted && ! isHardwareAccelerated () ) {
44354452 setChildrenDrawnWithCacheEnabled (true );
44364453 setChildrenDrawingCacheEnabled (true );
44374454 mCachingStarted = mCachingActive = true ;
44384455 }
44394456 }
44404457
44414458 private void clearScrollingCache () {
4442- if (mClearScrollingCache == null ) {
4443- mClearScrollingCache = new Runnable () {
4444- public void run () {
4445- if (mCachingStarted ) {
4446- mCachingStarted = mCachingActive = false ;
4447- setChildrenDrawnWithCacheEnabled (false );
4448- if ((mPersistentDrawingCache & PERSISTENT_SCROLLING_CACHE ) == 0 ) {
4449- setChildrenDrawingCacheEnabled (false );
4450- }
4451- if (!isAlwaysDrawnWithCacheEnabled ()) {
4452- invalidate ();
4459+ if (!isHardwareAccelerated ()) {
4460+ if (mClearScrollingCache == null ) {
4461+ mClearScrollingCache = new Runnable () {
4462+ public void run () {
4463+ if (mCachingStarted ) {
4464+ mCachingStarted = mCachingActive = false ;
4465+ setChildrenDrawnWithCacheEnabled (false );
4466+ if ((mPersistentDrawingCache & PERSISTENT_SCROLLING_CACHE ) == 0 ) {
4467+ setChildrenDrawingCacheEnabled (false );
4468+ }
4469+ if (!isAlwaysDrawnWithCacheEnabled ()) {
4470+ invalidate ();
4471+ }
44534472 }
44544473 }
4455- }
4456- };
4474+ };
4475+ }
4476+ post (mClearScrollingCache );
44574477 }
4458- post (mClearScrollingCache );
44594478 }
44604479
44614480 /**
@@ -4599,14 +4618,18 @@ boolean trackMotionScroll(int deltaY, int incrementalDeltaY) {
45994618 mRecycler .removeSkippedScrap ();
46004619 }
46014620
4621+ // invalidate before moving the children to avoid unnecessary invalidate
4622+ // calls to bubble up from the children all the way to the top
4623+ if (!awakenScrollBars ()) {
4624+ invalidate ();
4625+ }
4626+
46024627 offsetChildrenTopAndBottom (incrementalDeltaY );
46034628
46044629 if (down ) {
46054630 mFirstPosition += count ;
46064631 }
46074632
4608- invalidate ();
4609-
46104633 final int absIncrementalDeltaY = Math .abs (incrementalDeltaY );
46114634 if (spaceAbove < absIncrementalDeltaY || spaceBelow < absIncrementalDeltaY ) {
46124635 fillGap (down );
@@ -4629,7 +4652,6 @@ boolean trackMotionScroll(int deltaY, int incrementalDeltaY) {
46294652 mBlockLayoutRequests = false ;
46304653
46314654 invokeOnItemScrollListener ();
4632- awakenScrollBars ();
46334655
46344656 return false ;
46354657 }
0 commit comments