From 9fb31d15381647c7c7a28ebe28f8a8676d65eb19 Mon Sep 17 00:00:00 2001 From: Blair Vanderhoof Date: Wed, 22 May 2019 13:20:03 -0700 Subject: [PATCH] Fix layout animation crash Summary: As of D14529038, LayoutAnimations can sometimes throw an exception due to the view being null. This can happen when elements are removed/added and is not fixable in product code. This is a temporary fix - the root cause for this issue will be fixed soon. Reviewed By: lunaleaps Differential Revision: D15428791 fbshipit-source-id: 41200e572ed7d5d470754792c5576a0ea23fe946 --- .../react/uimanager/NativeViewHierarchyManager.java | 2 +- .../layoutanimation/LayoutAnimationController.java | 12 ++++++++---- .../facebook/react/views/view/ReactViewGroup.java | 4 +++- 3 files changed, 12 insertions(+), 6 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 48d1daefd5f..2aa8abf9794 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java @@ -444,7 +444,7 @@ public class NativeViewHierarchyManager { arrayContains(tagsToDelete, viewToRemove.getId())) { // The view will be removed and dropped by the 'delete' layout animation // instead, so do nothing - } else { + } else if (viewToManage != null) { viewManager.removeViewAt(viewToManage, normalizedIndexToRemove); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/LayoutAnimationController.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/LayoutAnimationController.java index 232cb01f907..cad0a0cac29 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/LayoutAnimationController.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/LayoutAnimationController.java @@ -82,10 +82,14 @@ public class LayoutAnimationController { } public boolean shouldAnimateLayout(View viewToAnimate) { - // if view parent is null, skip animation: view have been clipped, we don't want animation to - // resume when view is re-attached to parent, which is the standard android animation behavior. - // If there's a layout handling animation going on, it should be animated nonetheless since the - // ongoing animation needs to be updated. + // if view is null or the view parent is null, skip animation: view have been clipped, + // we don't want animation to resume when view is re-attached to parent, which is the + // standard android animation behavior. If there's a layout handling animation going on, + // it should be animated nonetheless since the ongoing animation needs to be updated. + + if (viewToAnimate == null) { + return false; + } return (mShouldAnimateLayout && viewToAnimate.getParent() != null) || mLayoutHandlers.get(viewToAnimate.getId()) != null; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java index 4e89e9dbf59..e1cec5d41a2 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java @@ -465,7 +465,9 @@ public class ReactViewGroup extends ViewGroup implements mDrawingOrderHelper.handleRemoveView(getChildAt(index)); setChildrenDrawingOrderEnabled(mDrawingOrderHelper.shouldEnableCustomDrawingOrder()); - super.removeViewAt(index); + if (getChildAt(index) != null) { + super.removeViewAt(index); + } } @Override