[go: nahoru, domu]

Ensure views are visible when popping a reordered hide

When an exiting fragment uses transitions and does a hide in a
FragmentTransaction that allows reordering, if that transaction is
popped the Fragment views are still invisible.

This is because when reordering is allowed on an exiting fragment, the
exiting views are set to INVISIBLE. When the transaction is popped,
the Fragment view instance is new, but if the child views of the
Fragment view has ids, the same views are restored. These views are
still set to INVISIBLE, and therefore these views are ignored.

This change ensures that the entering Fragment view and its children are
set to VISIBlE so they can properly do any transitions.

Test: All tests pass
BUG: 70793925
Change-Id: I4f26981afdb49ec9f262b8e46fc63147858551a5
(cherry picked from commit 616f2c0c64d478766f77c632bc106f602b79528a)
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentTransition.java b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentTransition.java
index 3b9cf40..dd243cc 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentTransition.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentTransition.java
@@ -261,7 +261,7 @@
         ArrayList<View> exitingViews = configureEnteringExitingViews(impl, exitTransition,
                 outFragment, sharedElementsOut, nonExistentView);
 
-        ArrayList<View> enteringViews = configureEnteringExitingViews(impl, enterTransition,
+        ArrayList<View> enteringViews = configureEnteringViewsReordered(impl, enterTransition,
                 inFragment, sharedElementsIn, nonExistentView);
 
         setViewVisibility(enteringViews, View.INVISIBLE);
@@ -1061,6 +1061,34 @@
         return viewList;
     }
 
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    static ArrayList<View> configureEnteringViewsReordered(FragmentTransitionImpl impl,
+            Object transition,
+            Fragment fragment, ArrayList<View> sharedElements, View nonExistentView) {
+        if (fragment != null) {
+            changeViewVisibility(fragment.mView, View.VISIBLE);
+        }
+        return configureEnteringExitingViews(impl, transition, fragment, sharedElements,
+                nonExistentView);
+    }
+
+
+    /**
+     * Sets the visibility of a View and its children.
+     */
+    private static void changeViewVisibility(View view, int visibility) {
+        if (view instanceof ViewGroup) {
+            ViewGroup viewGroup = (ViewGroup) view;
+            int count = viewGroup.getChildCount();
+            for (int i = 0; i < count; i++) {
+                View child = viewGroup.getChildAt(i);
+                changeViewVisibility(child, visibility);
+            }
+        } else {
+            view.setVisibility(visibility);
+        }
+    }
+
     /**
      * Sets the visibility of all Views in {@code views} to {@code visibility}.
      */