From 9f00752a97db3fe0b03cb412c5357eeebc3e2b16 Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Thu, 24 Sep 2020 11:57:06 -0700 Subject: [PATCH] LayoutAnimations: force props to update when executing "final" mutations Summary: When an animation is completed or a conflicting animation is detected, force props, state, layout, etc to update. Currently, when a final animation mutation is queued, some attributes can be updated but not others, causing unexpected visual glitches at least on Android. Some of these are arguably component bugs, but it's easier to just flush all attributes by tricking the platforms into updating all attributes. This will also prevent us from having to track down more of these bugs, potentially. Changelog: [Internal] Reviewed By: sammy-SC Differential Revision: D23886519 fbshipit-source-id: 8e5081bbe3b7843c16c0f283fa07fdec0e211aa8 --- .../renderer/animations/LayoutAnimationDriver.cpp | 9 +++++++-- .../animations/LayoutAnimationKeyFrameManager.cpp | 11 ++++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/ReactCommon/react/renderer/animations/LayoutAnimationDriver.cpp b/ReactCommon/react/renderer/animations/LayoutAnimationDriver.cpp index c9f5b13ab0c..d6b46c68a01 100644 --- a/ReactCommon/react/renderer/animations/LayoutAnimationDriver.cpp +++ b/ReactCommon/react/renderer/animations/LayoutAnimationDriver.cpp @@ -203,10 +203,15 @@ void LayoutAnimationDriver::animationMutationsForFrame( // Copy so that if something else mutates the inflight animations, it // won't change this mutation after this point. + ShadowView oldShadowView{}; + if (finalMutationForKeyFrame.type != + ShadowViewMutation::Type::Update) { + oldShadowView = finalMutationForKeyFrame.oldChildShadowView; + } mutationsList.push_back( ShadowViewMutation{finalMutationForKeyFrame.type, finalMutationForKeyFrame.parentShadowView, - finalMutationForKeyFrame.oldChildShadowView, + oldShadowView, finalMutationForKeyFrame.newChildShadowView, finalMutationForKeyFrame.index}); } else { @@ -217,7 +222,7 @@ void LayoutAnimationDriver::animationMutationsForFrame( mutationsList.push_back( ShadowViewMutation{ShadowViewMutation::Type::Update, keyframe.parentView, - keyframe.viewStart, + {}, keyframe.viewEnd, -1}); } diff --git a/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.cpp b/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.cpp index 08fbe459d7a..4264be5d3c6 100644 --- a/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.cpp +++ b/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.cpp @@ -1212,7 +1212,16 @@ LayoutAnimationKeyFrameManager::pullTransaction( auto &keyFrame = std::get<0>(conflictingKeyframeTuple); if (keyFrame.finalMutationForKeyFrame.hasValue()) { auto &mutation = *keyFrame.finalMutationForKeyFrame; - finalConflictingMutations.push_back(mutation); + if (mutation.type == ShadowViewMutation::Type::Update) { + finalConflictingMutations.push_back( + ShadowViewMutation::UpdateMutation( + mutation.parentShadowView, + {}, + mutation.newChildShadowView, + mutation.index)); + } else { + finalConflictingMutations.push_back(mutation); + } } }