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
This commit is contained in:
Luna Wei 2020-03-23 17:30:52 -07:00 коммит произвёл Facebook GitHub Bot
Родитель 15434c7c43
Коммит 44f213b40e
1 изменённых файлов: 23 добавлений и 2 удалений

Просмотреть файл

@ -36,6 +36,7 @@ import com.facebook.react.uimanager.layoutanimation.LayoutAnimationListener;
import com.facebook.systrace.Systrace; import com.facebook.systrace.Systrace;
import com.facebook.systrace.SystraceMessage; import com.facebook.systrace.SystraceMessage;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import javax.annotation.concurrent.NotThreadSafe; import javax.annotation.concurrent.NotThreadSafe;
@ -83,6 +84,7 @@ public class NativeViewHierarchyManager {
private boolean mLayoutAnimationEnabled; private boolean mLayoutAnimationEnabled;
private PopupMenu mPopupMenu; private PopupMenu mPopupMenu;
private int mDroppedViewIndex = 0; private int mDroppedViewIndex = 0;
private HashMap<Integer, Set<Integer>> mPendingDeletionsForTag;
public NativeViewHierarchyManager(ViewManagerRegistry viewManagers) { public NativeViewHierarchyManager(ViewManagerRegistry viewManagers) {
this(viewManagers, new RootViewManager()); this(viewManagers, new RootViewManager());
@ -352,6 +354,18 @@ public class NativeViewHierarchyManager {
return stringBuilder.toString(); return stringBuilder.toString();
} }
private Set<Integer> getPendingDeletionsForTag(int tag) {
if (mPendingDeletionsForTag == null) {
mPendingDeletionsForTag = new HashMap<>();
}
if (!mPendingDeletionsForTag.containsKey(tag)) {
mPendingDeletionsForTag.put(tag, new HashSet<Integer>());
}
return mPendingDeletionsForTag.get(tag);
}
/** /**
* @param tag react tag of the node we want to manage * @param tag react tag of the node we want to manage
* @param indicesToRemove ordered (asc) list of indicies at which view should be removed * @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 * @param tagsToDelete list of tags corresponding to views that should be removed
*/ */
public synchronized void manageChildren( public synchronized void manageChildren(
int tag, final int tag,
@Nullable int[] indicesToRemove, @Nullable int[] indicesToRemove,
@Nullable ViewAtIndex[] viewsToAdd, @Nullable ViewAtIndex[] viewsToAdd,
@Nullable int[] tagsToDelete) { @Nullable int[] tagsToDelete) {
UiThreadUtil.assertOnUiThread(); UiThreadUtil.assertOnUiThread();
final Set<Integer> pendingDeletionTags = new HashSet<>(); final Set<Integer> pendingDeletionTags = getPendingDeletionsForTag(tag);
final ViewGroup viewToManage = (ViewGroup) mTagsToViews.get(tag); final ViewGroup viewToManage = (ViewGroup) mTagsToViews.get(tag);
final ViewGroupManager viewManager = (ViewGroupManager) resolveViewManager(tag); final ViewGroupManager viewManager = (ViewGroupManager) resolveViewManager(tag);
if (viewToManage == null) { if (viewToManage == null) {
@ -379,6 +393,7 @@ public class NativeViewHierarchyManager {
} }
int lastIndexToRemove = viewManager.getChildCount(viewToManage); int lastIndexToRemove = viewManager.getChildCount(viewToManage);
if (indicesToRemove != null) { if (indicesToRemove != null) {
for (int i = indicesToRemove.length - 1; i >= 0; i--) { for (int i = indicesToRemove.length - 1; i >= 0; i--) {
int indexToRemove = indicesToRemove[i]; int indexToRemove = indicesToRemove[i];
@ -461,6 +476,9 @@ public class NativeViewHierarchyManager {
viewManager.removeView(viewToManage, viewToDestroy); viewManager.removeView(viewToManage, viewToDestroy);
dropView(viewToDestroy); dropView(viewToDestroy);
pendingDeletionTags.remove(viewToDestroy.getId()); pendingDeletionTags.remove(viewToDestroy.getId());
if (pendingDeletionTags.isEmpty()) {
mPendingDeletionsForTag.remove(tag);
}
} }
}); });
} else { } else {
@ -501,6 +519,9 @@ public class NativeViewHierarchyManager {
viewManager.addView(viewToManage, viewToAdd, normalizedIndex); viewManager.addView(viewToManage, viewToAdd, normalizedIndex);
} }
} }
if (pendingDeletionTags.isEmpty()) {
mPendingDeletionsForTag.remove(tag);
}
} }
private boolean arrayContains(@Nullable int[] array, int ele) { private boolean arrayContains(@Nullable int[] array, int ele) {