From 44f213b40e408f58ef7c3db387b4f72e76e7b7bd Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Mon, 23 Mar 2020 17:30:52 -0700 Subject: [PATCH] Modify pending deletion tags to be cross manageChildren Summary: Changelog: [Internal] Removing historic layout animations index adjustment (D20323928) broke the Dating Secret Crush screen. Since flushing animations (D20319824) had to be reverted due to issues with Saved + Privacy Shortcuts (https://fburl.com/tasks/eijtmifu) we need to track pending deletions across `manageChildren` operations. Reviewed By: JoshuaGross Differential Revision: D20601079 fbshipit-source-id: c6f116683750e97abe7f988cf361d2a6449e90e6 --- .../uimanager/NativeViewHierarchyManager.java | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java index c3d19ecbe7..d1de220c55 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java @@ -36,6 +36,7 @@ import com.facebook.react.uimanager.layoutanimation.LayoutAnimationListener; import com.facebook.systrace.Systrace; import com.facebook.systrace.SystraceMessage; import java.util.Arrays; +import java.util.HashMap; import java.util.HashSet; import java.util.Set; import javax.annotation.concurrent.NotThreadSafe; @@ -83,6 +84,7 @@ public class NativeViewHierarchyManager { private boolean mLayoutAnimationEnabled; private PopupMenu mPopupMenu; private int mDroppedViewIndex = 0; + private HashMap> mPendingDeletionsForTag; public NativeViewHierarchyManager(ViewManagerRegistry viewManagers) { this(viewManagers, new RootViewManager()); @@ -352,6 +354,18 @@ public class NativeViewHierarchyManager { return stringBuilder.toString(); } + private Set getPendingDeletionsForTag(int tag) { + if (mPendingDeletionsForTag == null) { + mPendingDeletionsForTag = new HashMap<>(); + } + + if (!mPendingDeletionsForTag.containsKey(tag)) { + mPendingDeletionsForTag.put(tag, new HashSet()); + } + + return mPendingDeletionsForTag.get(tag); + } + /** * @param tag react tag of the node we want to manage * @param indicesToRemove ordered (asc) list of indicies at which view should be removed @@ -360,13 +374,13 @@ public class NativeViewHierarchyManager { * @param tagsToDelete list of tags corresponding to views that should be removed */ public synchronized void manageChildren( - int tag, + final int tag, @Nullable int[] indicesToRemove, @Nullable ViewAtIndex[] viewsToAdd, @Nullable int[] tagsToDelete) { UiThreadUtil.assertOnUiThread(); - final Set pendingDeletionTags = new HashSet<>(); + final Set pendingDeletionTags = getPendingDeletionsForTag(tag); final ViewGroup viewToManage = (ViewGroup) mTagsToViews.get(tag); final ViewGroupManager viewManager = (ViewGroupManager) resolveViewManager(tag); if (viewToManage == null) { @@ -379,6 +393,7 @@ public class NativeViewHierarchyManager { } int lastIndexToRemove = viewManager.getChildCount(viewToManage); + if (indicesToRemove != null) { for (int i = indicesToRemove.length - 1; i >= 0; i--) { int indexToRemove = indicesToRemove[i]; @@ -461,6 +476,9 @@ public class NativeViewHierarchyManager { viewManager.removeView(viewToManage, viewToDestroy); dropView(viewToDestroy); pendingDeletionTags.remove(viewToDestroy.getId()); + if (pendingDeletionTags.isEmpty()) { + mPendingDeletionsForTag.remove(tag); + } } }); } else { @@ -501,6 +519,9 @@ public class NativeViewHierarchyManager { viewManager.addView(viewToManage, viewToAdd, normalizedIndex); } } + if (pendingDeletionTags.isEmpty()) { + mPendingDeletionsForTag.remove(tag); + } } private boolean arrayContains(@Nullable int[] array, int ele) {