C++ LayoutAnimations: solve crash when "animating" virtual views
Summary: Index adjustment doesn't work if virtual views are inserted, because those don't actually result in the view hierarchy being mutated, as such. Add an Android-specific check to solve the crash. I don't love adding platform-specific checks here, so I'm considering wrapping this logic in a platform-specific class, so that logic lives outside of the core of LayoutAnimations and entirely in platform code. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D21727805 fbshipit-source-id: 5af2cf479beaa4d0e9d94ea16ac989c4268920f8
This commit is contained in:
Родитель
68c0eddb71
Коммит
8b2eb3766b
|
@ -311,6 +311,10 @@ void LayoutAnimationKeyFrameManager::adjustDelayedMutationIndicesForMutation(
|
||||||
bool isInsertMutation = mutation.type == ShadowViewMutation::Type::Insert;
|
bool isInsertMutation = mutation.type == ShadowViewMutation::Type::Insert;
|
||||||
assert(isRemoveMutation || isInsertMutation);
|
assert(isRemoveMutation || isInsertMutation);
|
||||||
|
|
||||||
|
if (mutatedViewIsVirtual(mutation)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto &inflightAnimation : inflightAnimations_) {
|
for (auto &inflightAnimation : inflightAnimations_) {
|
||||||
if (inflightAnimation.surfaceId != surfaceId) {
|
if (inflightAnimation.surfaceId != surfaceId) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -691,7 +695,8 @@ LayoutAnimationKeyFrameManager::pullTransaction(
|
||||||
for (const auto &otherMutation : mutations) {
|
for (const auto &otherMutation : mutations) {
|
||||||
if (otherMutation.type == ShadowViewMutation::Type::Insert &&
|
if (otherMutation.type == ShadowViewMutation::Type::Insert &&
|
||||||
otherMutation.parentShadowView.tag == parentTag) {
|
otherMutation.parentShadowView.tag == parentTag) {
|
||||||
if (otherMutation.index <= adjustedIndex) {
|
if (otherMutation.index <= adjustedIndex &&
|
||||||
|
!mutatedViewIsVirtual(otherMutation)) {
|
||||||
adjustedIndex++;
|
adjustedIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -861,6 +866,22 @@ LayoutAnimationKeyFrameManager::pullTransaction(
|
||||||
surfaceId, transactionNumber, std::move(mutations), {}};
|
surfaceId, transactionNumber, std::move(mutations), {}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LayoutAnimationKeyFrameManager::mutatedViewIsVirtual(
|
||||||
|
ShadowViewMutation const &mutation) const {
|
||||||
|
bool viewIsVirtual = false;
|
||||||
|
|
||||||
|
// TODO: extract this into an Android platform-specific class
|
||||||
|
// Explanation: for "Insert" mutations, oldChildShadowView is always empty.
|
||||||
|
// for "Remove" mutations, newChildShadowView is always empty.
|
||||||
|
#ifdef ANDROID
|
||||||
|
viewIsVirtual =
|
||||||
|
mutation.newChildShadowView.layoutMetrics == EmptyLayoutMetrics &&
|
||||||
|
mutation.oldChildShadowView.layoutMetrics == EmptyLayoutMetrics;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return viewIsVirtual;
|
||||||
|
}
|
||||||
|
|
||||||
ComponentDescriptor const &
|
ComponentDescriptor const &
|
||||||
LayoutAnimationKeyFrameManager::getComponentDescriptorForShadowView(
|
LayoutAnimationKeyFrameManager::getComponentDescriptorForShadowView(
|
||||||
ShadowView const &shadowView) const {
|
ShadowView const &shadowView) const {
|
||||||
|
|
|
@ -144,6 +144,8 @@ class LayoutAnimationKeyFrameManager : public UIManagerAnimationDelegate,
|
||||||
ShadowViewMutation const &mutation) const;
|
ShadowViewMutation const &mutation) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
bool mutatedViewIsVirtual(ShadowViewMutation const &mutation) const;
|
||||||
|
|
||||||
ComponentDescriptor const &getComponentDescriptorForShadowView(
|
ComponentDescriptor const &getComponentDescriptorForShadowView(
|
||||||
ShadowView const &shadowView) const;
|
ShadowView const &shadowView) const;
|
||||||
std::pair<double, double> calculateAnimationProgress(
|
std::pair<double, double> calculateAnimationProgress(
|
||||||
|
|
Загрузка…
Ссылка в новой задаче