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
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 80b5dad..7713bd8 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6434,8 +6434,10 @@
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 @@
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;
@@ -8074,6 +8082,15 @@
}
/**
+ * 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
* in the future. This must be called from a UI thread. To call from a non-UI
@@ -8087,9 +8104,7 @@
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 @@
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 @@
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 @@
* @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) ||
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 7c826ca9..0e420d6 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -4749,6 +4749,15 @@
}
/**
+ * 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,
* should be kept around (re-displayed when the ViewGroup draws its children) even if it