Merge "Disable suppressLayout in Visibility Activity Transitoins." into nyc-dev
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index 198bfb0a..e589e7c 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -25,6 +25,7 @@
 import android.os.ResultReceiver;
 import android.transition.Transition;
 import android.transition.TransitionSet;
+import android.transition.Visibility;
 import android.util.ArrayMap;
 import android.view.GhostView;
 import android.view.View;
@@ -378,6 +379,7 @@
             transition.setEpicenterCallback(mEpicenterCallback);
             transition = setTargets(transition, includeTransitioningViews);
         }
+        noLayoutSuppressionForVisibilityTransitions(transition);
         return transition;
     }
 
@@ -944,6 +946,24 @@
         }
     }
 
+    /**
+     * Blocks suppressLayout from Visibility transitions. It is ok to suppress the layout,
+     * but we don't want to force the layout when suppressLayout becomes false. This leads
+     * to visual glitches.
+     */
+    private static void noLayoutSuppressionForVisibilityTransitions(Transition transition) {
+        if (transition instanceof Visibility) {
+            final Visibility visibility = (Visibility) transition;
+            visibility.setSuppressLayout(false);
+        } else if (transition instanceof TransitionSet) {
+            final TransitionSet set = (TransitionSet) transition;
+            final int count = set.getTransitionCount();
+            for (int i = 0; i < count; i++) {
+                noLayoutSuppressionForVisibilityTransitions(set.getTransitionAt(i));
+            }
+        }
+    }
+
     private static class FixedEpicenterCallback extends Transition.EpicenterCallback {
         private Rect mEpicenter;
 
diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java
index 4eaab37..6579212 100644
--- a/core/java/android/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -84,6 +84,7 @@
     }
 
     private int mMode = MODE_IN | MODE_OUT;
+    private boolean mSuppressLayout = true;
 
     public Visibility() {}
 
@@ -98,6 +99,15 @@
     }
 
     /**
+     * This tells the Visibility transition to suppress layout during the transition and release
+     * the suppression after the transition.
+     * @hide
+     */
+    public void setSuppressLayout(boolean suppress) {
+        this.mSuppressLayout = suppress;
+    }
+
+    /**
      * Changes the transition to support appearing and/or disappearing Views, depending
      * on <code>mode</code>.
      *
@@ -428,7 +438,7 @@
             Animator animator = onDisappear(sceneRoot, viewToKeep, startValues, endValues);
             if (animator != null) {
                 DisappearListener disappearListener = new DisappearListener(viewToKeep,
-                        finalVisibility);
+                        finalVisibility, mSuppressLayout);
                 animator.addListener(disappearListener);
                 animator.addPauseListener(disappearListener);
                 addListener(disappearListener);
@@ -483,14 +493,16 @@
         private final View mView;
         private final int mFinalVisibility;
         private final ViewGroup mParent;
+        private final boolean mSuppressLayout;
 
         private boolean mLayoutSuppressed;
         boolean mCanceled = false;
 
-        public DisappearListener(View view, int finalVisibility) {
+        public DisappearListener(View view, int finalVisibility, boolean suppressLayout) {
             this.mView = view;
             this.mFinalVisibility = finalVisibility;
             this.mParent = (ViewGroup) view.getParent();
+            this.mSuppressLayout = suppressLayout;
             // Prevent a layout from including mView in its calculation.
             suppressLayout(true);
         }
@@ -555,7 +567,7 @@
         }
 
         private void suppressLayout(boolean suppress) {
-            if (mLayoutSuppressed != suppress && mParent != null) {
+            if (mSuppressLayout && mLayoutSuppressed != suppress && mParent != null) {
                 mLayoutSuppressed = suppress;
                 mParent.suppressLayout(suppress);
             }