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

Commit aceafe63 authored by Chet Haase's avatar Chet Haase
Browse files

Fixed error in invalidation/LayoutTransition logic

A recent fix for invalidation noop'd calls to invalidate() on
GONE/INVISIBLE views. This logic also noop'd views which might
be GONE, but which are in the process of fading in/out via
LayoutTransition animations. These views should invalidate as
usual.

Change-Id: Ie90a340f70290391a3aa4e68df535c6aabf4e5eb
parent e598cd01
Loading
Loading
Loading
Loading
+23 −14
Original line number Diff line number Diff line
@@ -6434,8 +6434,10 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
            if ((changed & VISIBILITY_MASK) != 0) {
                /*
                 * If this view is becoming visible, invalidate it in case it changed while
                 * it was not visible.
                 * it was not visible. Marking it drawn ensures that the invalidation will
                 * go through.
                 */
                mPrivateFlags |= DRAWN;
                invalidate(true);
                needGlobalAttributesUpdate(true);
@@ -6454,11 +6456,17 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
        if ((changed & GONE) != 0) {
            needGlobalAttributesUpdate(false);
            requestLayout();
            invalidate(true);
            if (((mViewFlags & VISIBILITY_MASK) == GONE)) {
                if (hasFocus()) clearFocus();
                destroyDrawingCache();
                if (mParent instanceof View) {
                    // GONE views noop invalidation, so invalidate the parent
                    ((View) mParent).invalidate(true);
                }
                // Mark the view drawn to ensure that it gets invalidated properly the next
                // time it is visible and gets invalidated
                mPrivateFlags |= DRAWN;
            }
            if (mAttachInfo != null) {
                mAttachInfo.mViewVisibilityChanged = true;
@@ -8073,6 +8081,15 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
        return false;
    }
    /**
     * Do not invalidate views which are not visible and which are not running an animation. They
     * will not get drawn and they should not set dirty flags as if they will be drawn
     */
    private boolean skipInvalidate() {
        return (mViewFlags & VISIBILITY_MASK) != VISIBLE && mCurrentAnimation == null &&
                (!(mParent instanceof ViewGroup) ||
                        !((ViewGroup) mParent).isViewTransitioning(this));
    }
    /**
     * Mark the the area defined by dirty as needing to be drawn. If the view is
     * visible, {@link #onDraw(android.graphics.Canvas)} will be called at some point
@@ -8087,9 +8104,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
            ViewDebug.trace(this, ViewDebug.HierarchyTraceType.INVALIDATE);
        }
        if ((mViewFlags & VISIBILITY_MASK) != VISIBLE && mCurrentAnimation == null) {
            // Noop for views which are not visible and which are not running an animation. They
            // will not get drawn and they should not set dirty flags as if they will be drawn
        if (skipInvalidate()) {
            return;
        }
        if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) ||
@@ -8135,9 +8150,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
            ViewDebug.trace(this, ViewDebug.HierarchyTraceType.INVALIDATE);
        }
        if ((mViewFlags & VISIBILITY_MASK) != VISIBLE && mCurrentAnimation == null) {
            // Noop for views which are not visible and which are not running an animation. They
            // will not get drawn and they should not set dirty flags as if they will be drawn
        if (skipInvalidate()) {
            return;
        }
        if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) ||
@@ -8192,9 +8205,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
            ViewDebug.trace(this, ViewDebug.HierarchyTraceType.INVALIDATE);
        }
        if ((mViewFlags & VISIBILITY_MASK) != VISIBLE && mCurrentAnimation == null) {
            // Noop for views which are not visible and which are not running an animation. They
            // will not get drawn and they should not set dirty flags as if they will be drawn
        if (skipInvalidate()) {
            return;
        }
        if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) ||
@@ -8232,9 +8243,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
     * @hide
     */
    public void fastInvalidate() {
        if ((mViewFlags & VISIBILITY_MASK) != VISIBLE && mCurrentAnimation == null) {
            // Noop for views which are not visible and which are not running an animation. They
            // will not get drawn and they should not set dirty flags as if they will be drawn
        if (skipInvalidate()) {
            return;
        }
        if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) ||
+9 −0
Original line number Diff line number Diff line
@@ -4748,6 +4748,15 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        }
    }

    /**
     * Utility function called by View during invalidation to determine whether a view that
     * is invisible or gone should still be invalidated because it is being transitioned (and
     * therefore still needs to be drawn).
     */
    boolean isViewTransitioning(View view) {
        return (mTransitioningViews != null && mTransitioningViews.contains(view));
    }

    /**
     * This method tells the ViewGroup that the given View object, which should have this
     * ViewGroup as its parent,