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.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<Integer, Set<Integer>> mPendingDeletionsForTag;
public NativeViewHierarchyManager(ViewManagerRegistry viewManagers) {
this(viewManagers, new RootViewManager());
@ -352,6 +354,18 @@ public class NativeViewHierarchyManager {
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 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<Integer> pendingDeletionTags = new HashSet<>();
final Set<Integer> 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) {