Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c3da1b44 authored by Romain Guy's avatar Romain Guy Committed by Android (Google) Code Review
Browse files

Merge "Optimize invalidate calls in lists."

parents 0e9241df 9d849a2f
Loading
Loading
Loading
Loading
+57 −35
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
        ViewTreeObserver.OnTouchModeChangeListener,
        RemoteViewsAdapter.RemoteAdapterConnectionCallback {

    @SuppressWarnings("UnusedDeclaration")
    private static final String TAG = "AbsListView";

    /**
@@ -2429,7 +2430,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
        final ViewTreeObserver treeObserver = getViewTreeObserver();
        treeObserver.removeOnTouchModeChangeListener(this);
        if (mTextFilterEnabled && mPopup != null) {
            treeObserver.removeGlobalOnLayoutListener(this);
            treeObserver.removeOnGlobalLayoutListener(this);
            mGlobalLayoutListenerAddedFilter = false;
        }

@@ -2943,11 +2944,23 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                            mDirection = 0; // Reset when entering overscroll.
                            mTouchMode = TOUCH_MODE_OVERSCROLL;
                            if (rawDeltaY > 0) {
                                if (!mEdgeGlowTop.isIdle()) {
                                    invalidate(mEdgeGlowTop.getBounds());
                                } else {
                                    invalidate();
                                }

                                mEdgeGlowTop.onPull((float) overscroll / getHeight());
                                if (!mEdgeGlowBottom.isFinished()) {
                                    mEdgeGlowBottom.onRelease();
                                }
                            } else if (rawDeltaY < 0) {
                                if (!mEdgeGlowBottom.isIdle()) {
                                    invalidate(mEdgeGlowBottom.getBounds());
                                } else {
                                    invalidate();
                                }

                                mEdgeGlowBottom.onPull((float) overscroll / getHeight());
                                if (!mEdgeGlowTop.isFinished()) {
                                    mEdgeGlowTop.onRelease();
@@ -2956,7 +2969,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                        }
                    }
                    mMotionY = y;
                    invalidate();
                }
                mLastY = y;
            }
@@ -2990,25 +3002,25 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                            if (!mEdgeGlowBottom.isFinished()) {
                                mEdgeGlowBottom.onRelease();
                            }
                            invalidate(mEdgeGlowTop.getBounds());
                        } else if (rawDeltaY < 0) {
                            mEdgeGlowBottom.onPull((float) overScrollDistance / getHeight());
                            if (!mEdgeGlowTop.isFinished()) {
                                mEdgeGlowTop.onRelease();
                            }
                            invalidate(mEdgeGlowBottom.getBounds());
                        }
                        invalidate();
                    }
                }

                if (incrementalDeltaY != 0) {
                    // Coming back to 'real' list scrolling
                    if (mScrollY != 0) {
                        mScrollY = 0;
                        invalidateParentIfNeeded();
                    }

                    // No need to do all this work if we're not going to move anyway
                    if (incrementalDeltaY != 0) {
                    trackMotionScroll(incrementalDeltaY, incrementalDeltaY);
                    }

                    mTouchMode = TOUCH_MODE_SCROLL;

@@ -3468,11 +3480,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                final int rightPadding = mListPadding.right + mGlowPaddingRight;
                final int width = getWidth() - leftPadding - rightPadding;

                canvas.translate(leftPadding,
                        Math.min(0, scrollY + mFirstPositionDistanceGuess));
                int edgeY = Math.min(0, scrollY + mFirstPositionDistanceGuess);
                canvas.translate(leftPadding, edgeY);
                mEdgeGlowTop.setSize(width, getHeight());
                if (mEdgeGlowTop.draw(canvas)) {
                    invalidate();
                    mEdgeGlowTop.setPosition(leftPadding, edgeY);
                    invalidate(mEdgeGlowTop.getBounds());
                }
                canvas.restoreToCount(restoreCount);
            }
@@ -3483,12 +3496,15 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                final int width = getWidth() - leftPadding - rightPadding;
                final int height = getHeight();

                canvas.translate(-width + leftPadding,
                        Math.max(height, scrollY + mLastPositionDistanceGuess));
                int edgeX = -width + leftPadding;
                int edgeY = Math.max(height, scrollY + mLastPositionDistanceGuess);
                canvas.translate(edgeX, edgeY);
                canvas.rotate(180, width, 0);
                mEdgeGlowBottom.setSize(width, height);
                if (mEdgeGlowBottom.draw(canvas)) {
                    invalidate();
                    // Account for the rotation
                    mEdgeGlowBottom.setPosition(edgeX + width, edgeY - mEdgeGlowBottom.getHeight());
                    invalidate(mEdgeGlowBottom.getBounds());
                }
                canvas.restoreToCount(restoreCount);
            }
@@ -3874,7 +3890,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                }

                // Don't stop just because delta is zero (it could have been rounded)
                final boolean atEnd = trackMotionScroll(delta, delta) && (delta != 0);
                final boolean atEdge = trackMotionScroll(delta, delta);
                final boolean atEnd = atEdge && (delta != 0);
                if (atEnd) {
                    if (motionView != null) {
                        // Tweak the scroll for how far we overshot
@@ -3889,7 +3906,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                }

                if (more && !atEnd) {
                    invalidate();
                    if (atEdge) invalidate();
                    mLastFlingY = y;
                    post(this);
                } else {
@@ -4431,7 +4448,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
    }

    private void createScrollingCache() {
        if (mScrollingCacheEnabled && !mCachingStarted) {
        if (mScrollingCacheEnabled && !mCachingStarted && !isHardwareAccelerated()) {
            setChildrenDrawnWithCacheEnabled(true);
            setChildrenDrawingCacheEnabled(true);
            mCachingStarted = mCachingActive = true;
@@ -4439,6 +4456,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
    }

    private void clearScrollingCache() {
        if (!isHardwareAccelerated()) {
            if (mClearScrollingCache == null) {
                mClearScrollingCache = new Runnable() {
                    public void run() {
@@ -4457,6 +4475,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
            }
            post(mClearScrollingCache);
        }
    }

    /**
     * Track a motion scroll
@@ -4599,14 +4618,18 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
            mRecycler.removeSkippedScrap();
        }

        // invalidate before moving the children to avoid unnecessary invalidate
        // calls to bubble up from the children all the way to the top
        if (!awakenScrollBars()) {
            invalidate();
        }

        offsetChildrenTopAndBottom(incrementalDeltaY);

        if (down) {
            mFirstPosition += count;
        }

        invalidate();

        final int absIncrementalDeltaY = Math.abs(incrementalDeltaY);
        if (spaceAbove < absIncrementalDeltaY || spaceBelow < absIncrementalDeltaY) {
            fillGap(down);
@@ -4629,7 +4652,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
        mBlockLayoutRequests = false;

        invokeOnItemScrollListener();
        awakenScrollBars();

        return false;
    }
+44 −5
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.widget;

import android.graphics.Rect;
import com.android.internal.R;

import android.content.Context;
@@ -45,6 +46,7 @@ import android.view.animation.Interpolator;
 * {@link #draw(Canvas)} method.</p>
 */
public class EdgeEffect {
    @SuppressWarnings("UnusedDeclaration")
    private static final String TAG = "EdgeEffect";

    // Time it will take the effect to fully recede in ms
@@ -57,10 +59,7 @@ public class EdgeEffect {
    private static final int PULL_DECAY_TIME = 1000;

    private static final float MAX_ALPHA = 1.f;
    private static final float HELD_EDGE_ALPHA = 0.7f;
    private static final float HELD_EDGE_SCALE_Y = 0.5f;
    private static final float HELD_GLOW_ALPHA = 0.5f;
    private static final float HELD_GLOW_SCALE_Y = 0.5f;

    private static final float MAX_GLOW_HEIGHT = 4.f;

@@ -76,7 +75,9 @@ public class EdgeEffect {
    private final Drawable mGlow;
    private int mWidth;
    private int mHeight;
    private final int MIN_WIDTH = 300;
    private int mX;
    private int mY;
    private static final int MIN_WIDTH = 300;
    private final int mMinWidth;

    private float mEdgeAlpha;
@@ -120,6 +121,8 @@ public class EdgeEffect {

    private float mPullDistance;
    
    private final Rect mBounds = new Rect();

    /**
     * Construct a new EdgeEffect with a theme appropriate for the provided context.
     * @param context Context used to provide theming and resource information for the EdgeEffect
@@ -144,6 +147,29 @@ public class EdgeEffect {
        mHeight = height;
    }

    /**
     * Set the position of this edge effect in pixels. This position is
     * only used by {@link #getBounds()}.
     * 
     * @param x The position of the edge effect on the X axis
     * @param y The position of the edge effect on the Y axis
     */
    void setPosition(int x, int y) {
        mX = x;
        mY = y;
    }

    boolean isIdle() {
        return mState == STATE_IDLE;
    }

    /**
     * Returns the height of the effect itself.
     */
    int getHeight() {
        return Math.max(mGlow.getBounds().height(), mEdge.getBounds().height());
    }
    
    /**
     * Reports if this EdgeEffect's animation is finished. If this method returns false
     * after a call to {@link #draw(Canvas)} the host widget should schedule another
@@ -301,7 +327,6 @@ public class EdgeEffect {
        update();

        final int edgeHeight = mEdge.getIntrinsicHeight();
        final int edgeWidth = mEdge.getIntrinsicWidth();
        final int glowHeight = mGlow.getIntrinsicHeight();
        final int glowWidth = mGlow.getIntrinsicWidth();

@@ -334,9 +359,23 @@ public class EdgeEffect {
        }
        mEdge.draw(canvas);

        if (mState == STATE_RECEDE && glowBottom == 0 && edgeBottom == 0) {
            mState = STATE_IDLE;
        }

        return mState != STATE_IDLE;
    }

    /**
     * Returns the bounds of the edge effect.
     */
    public Rect getBounds() {
        mBounds.set(mGlow.getBounds());
        mBounds.union(mEdge.getBounds());
        mBounds.offset(mX, mY);
        return mBounds;
    }

    private void update() {
        final long time = AnimationUtils.currentAnimationTimeMillis();
        final float t = Math.min((time - mStartTime) / mDuration, 1.f);