diff --git a/frameworks/core/components_ng/pattern/view_context/view_context_model_ng.cpp b/frameworks/core/components_ng/pattern/view_context/view_context_model_ng.cpp index 1c259e38697f3c7371e7eb5bbef989adc9fc63e4..0ea94bf61b062bab6342f882829316d116f2c784 100644 --- a/frameworks/core/components_ng/pattern/view_context/view_context_model_ng.cpp +++ b/frameworks/core/components_ng/pattern/view_context/view_context_model_ng.cpp @@ -19,6 +19,8 @@ #include "core/pipeline_ng/pipeline_context.h" namespace OHOS::Ace::NG { +thread_local std::set ViewContextModelNG::pendingAnimationNodes_; + void ViewContextModelNG::closeAnimation(const AnimationOption& option, bool needFlush) { NG::ViewStackProcessor::GetInstance()->SetImplicitAnimationOption(option); @@ -29,7 +31,19 @@ void ViewContextModelNG::closeAnimation(const AnimationOption& option, bool need CHECK_NULL_VOID(container); auto pipelineContext = AceType::DynamicCast(container->GetPipelineContext()); CHECK_NULL_VOID(pipelineContext); + auto frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode(); + if (!pipelineContext->HasPendingAnimation()) { + if (pendingAnimationNodes_.find(frameNode) != pendingAnimationNodes_.end()) { + ACE_SCOPED_TRACE("Close current nested animation"); + TAG_LOGW(AceLogTag::ACE_ANIMATION, "Animation nested. Try to close current animation."); + AnimationUtils::CloseImplicitAnimation(); + pendingAnimationNodes_.erase(frameNode); + } + } pipelineContext->CloseFrontendAnimation(); + if (pendingAnimationNodes_.find(frameNode) != pendingAnimationNodes_.end()) { + pendingAnimationNodes_.erase(frameNode); + } } void ViewContextModelNG::openAnimation(const AnimationOption& option) @@ -41,7 +55,9 @@ void ViewContextModelNG::openAnimation(const AnimationOption& option) CHECK_NULL_VOID(container); auto pipelineContext = AceType::DynamicCast(container->GetPipelineContext()); CHECK_NULL_VOID(pipelineContext); + auto frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode(); pipelineContext->OpenFrontendAnimation(option, option.GetCurve(), option.GetOnFinishEvent()); + pendingAnimationNodes_.emplace(frameNode); bool isDirtyLayoutNodesEmpty = pipelineContext->IsDirtyLayoutNodesEmpty(); bool isDirtyPropertyNodesEmpty = pipelineContext->IsDirtyPropertyNodesEmpty(); if (option.GetIteration() == ANIMATION_REPEAT_INFINITE && !pipelineContext->IsLayouting() diff --git a/frameworks/core/components_ng/pattern/view_context/view_context_model_ng.h b/frameworks/core/components_ng/pattern/view_context/view_context_model_ng.h index c8fdfec28a59611d85e0736d6b46d035d8874260..13c37a63fb08bc3de020777b09a7f28680c5fe82 100644 --- a/frameworks/core/components_ng/pattern/view_context/view_context_model_ng.h +++ b/frameworks/core/components_ng/pattern/view_context/view_context_model_ng.h @@ -16,6 +16,8 @@ #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_FORM_FORM_MODEL_NG_H #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_FORM_FORM_MODEL_NG_H +#include + #include "core/components_ng/pattern/overlay/overlay_manager.h" #include "core/components_ng/pattern/view_context/view_context_model.h" @@ -36,6 +38,9 @@ public: const RefPtr& sheetContentNode, const NG::SheetStyle& sheetStyle, bool isPartialUpdate, int32_t currentInstanceId) override; int32_t CloseBindSheet(const RefPtr& sheetContentNode, int32_t currentInstanceId) override; + +private: + static thread_local std::set pendingAnimationNodes_; }; } // namespace OHOS::Ace::NG #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_FORM_FORM_MODEL_NG_H diff --git a/frameworks/core/pipeline/pipeline_base.h b/frameworks/core/pipeline/pipeline_base.h index 238974859ac167dfdeee691a36c31bfff1478e8f..25491ebde481f60a81ca4cf5100a3cb3e51a4741 100644 --- a/frameworks/core/pipeline/pipeline_base.h +++ b/frameworks/core/pipeline/pipeline_base.h @@ -164,6 +164,11 @@ public: void StartImplicitAnimation(const AnimationOption& operation, const RefPtr& curve, const std::function& finishCallback = nullptr, const std::optional& count = std::nullopt); + bool HasPendingAnimation() const + { + return !pendingFrontendAnimation_.empty(); + } + void PrepareCloseImplicitAnimation(); bool CloseImplicitAnimation();