diff --git a/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.cpp b/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.cpp index 687f4bc39355dd62902f404eedae2ed675dac23a..6cb451088eda1eb90ce8f5babeadd0195c75fe1f 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.cpp @@ -11328,7 +11328,7 @@ void JSViewAbstract::JsClickEffect(const JSCallbackInfo& info) void JSViewAbstract::JsOnVisibleAreaChange(const JSCallbackInfo& info) { - if (info.Length() != 2) { + if (info.Length() < 2 || info.Length() > 3) { return; } @@ -11366,7 +11366,17 @@ void JSViewAbstract::JsOnVisibleAreaChange(const JSCallbackInfo& info) PipelineContext::SetCallBackNode(node); func->ExecuteJS(2, params); }; - ViewAbstractModel::GetInstance()->SetOnVisibleChange(std::move(onVisibleChange), ratioVec); + + bool enhance = false; + if (info.Length() == 3 && info[2]->IsObject()) { + const auto& options = info[2]; + JSRef optionObj = JSRef::Cast(options); + JSRef enhanceVal = optionObj->GetProperty("allowBeyondBoundary"); + if (enhanceVal->IsBoolean()) { + enhance = enhanceVal->ToBoolean(); + } + } + ViewAbstractModel::GetInstance()->SetOnVisibleChange(std::move(onVisibleChange), ratioVec, enhance); } void JSViewAbstract::JsOnVisibleAreaApproximateChange(const JSCallbackInfo& info) diff --git a/frameworks/bridge/declarative_frontend/jsview/models/view_abstract_model_impl.cpp b/frameworks/bridge/declarative_frontend/jsview/models/view_abstract_model_impl.cpp index 657f4faf0ae6f4d188f84da7af1979ebf2f168bb..72d81c6a39807eccda445ebbcc86e8e11fb311be 100755 --- a/frameworks/bridge/declarative_frontend/jsview/models/view_abstract_model_impl.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/models/view_abstract_model_impl.cpp @@ -1252,7 +1252,7 @@ void ViewAbstractModelImpl::SetOnDrop(NG::OnDragDropFunc&& onDrop) } void ViewAbstractModelImpl::SetOnVisibleChange( - std::function&& onVisibleChange, const std::vector& ratios) + std::function&& onVisibleChange, const std::vector& ratios, bool enhance) { auto inspector = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent(); CHECK_NULL_VOID(inspector); diff --git a/frameworks/bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h b/frameworks/bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h index 78f7d1634e54b7a5da43e5f1e2b33224778665ab..48e3ed537f4bdc934404e484030a55e840eff8c7 100644 --- a/frameworks/bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h +++ b/frameworks/bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h @@ -242,8 +242,8 @@ public: void SetOnDragLeave(NG::OnDragDropFunc&& onDragLeave) override; void SetOnDragMove(NG::OnDragDropFunc&& onDragMove) override; void SetOnDrop(NG::OnDragDropFunc&& onDrop) override; - void SetOnVisibleChange( - std::function&& onVisibleChange, const std::vector& ratios) override; + void SetOnVisibleChange(std::function&& onVisibleChange, const std::vector& ratios, + bool enhance = false) override; void SetOnVisibleAreaApproximateChange(const std::function&& onVisibleChange, const std::vector& ratioList, int32_t expectedUpdateInterval) override {}; void SetOnAreaChanged( diff --git a/frameworks/core/components_ng/base/frame_node.cpp b/frameworks/core/components_ng/base/frame_node.cpp index 445956baee4a0a6e2f7b5308c57e19ca869df998..5fc230ac1d4ae59aff08a0715c3a35c4bf20f64b 100755 --- a/frameworks/core/components_ng/base/frame_node.cpp +++ b/frameworks/core/components_ng/base/frame_node.cpp @@ -2003,8 +2003,13 @@ void FrameNode::TriggerVisibleAreaChangeCallback( } } if (hasUserCallback) { - ProcessVisibleAreaChangeEvent( - visibleResult.visibleRect, visibleResult.frameRect, visibleAreaUserRatios, visibleAreaUserCallback, true); + if (visibleAreaUserCallback.option.enhance) { + ProcessVisibleAreaChangeEvent(visibleResult.innerVisibleRect, visibleResult.innerFrameRect, + visibleAreaUserRatios, visibleAreaUserCallback, true); + } else { + ProcessVisibleAreaChangeEvent(visibleResult.visibleRect, visibleResult.frameRect, visibleAreaUserRatios, + visibleAreaUserCallback, true); + } } } @@ -2021,6 +2026,10 @@ void FrameNode::ProcessVisibleAreaChangeEvent(const RectF& visibleRect, const Re NearEqual(currentVisibleRatio, lastVisibleRatio_) ? "non-execution" : "execution"); } if (isUser) { + if (visibleAreaCallback.option.enhance) { + auto rect = renderContext_->GetPaintRectWithoutTransform(); + currentVisibleRatio = rect.IsEmpty() ? VISIBLE_RATIO_MIN : currentVisibleRatio; + } if (!NearEqual(currentVisibleRatio, lastVisibleRatio_)) { auto lastVisibleCallbackRatio = lastVisibleCallbackRatio_; ProcessAllVisibleCallback( diff --git a/frameworks/core/components_ng/base/view_abstract.cpp b/frameworks/core/components_ng/base/view_abstract.cpp index 33c0a11812efdb1f6eb701864ef252c764daf390..960c6f4ea38bf3dee41706f771f72a58e876f264 100644 --- a/frameworks/core/components_ng/base/view_abstract.cpp +++ b/frameworks/core/components_ng/base/view_abstract.cpp @@ -2734,7 +2734,7 @@ void ViewAbstract::SetOnSizeChanged(std::function &&onVisibleChange, - const std::vector &ratioList) + const std::vector &ratioList, bool enhance) { auto pipeline = PipelineContext::GetCurrentContext(); CHECK_NULL_VOID(pipeline); @@ -2742,6 +2742,10 @@ void ViewAbstract::SetOnVisibleChange(std::function &&onVisi CHECK_NULL_VOID(frameNode); frameNode->CleanVisibleAreaUserCallback(); pipeline->AddVisibleAreaChangeNode(frameNode, ratioList, onVisibleChange); + auto eventHub = frameNode->GetEventHub(); + CHECK_NULL_VOID(eventHub); + auto& visibleAreaUserCallback = eventHub->GetVisibleAreaCallback(true); + visibleAreaUserCallback.option = { enhance }; } void ViewAbstract::SetResponseRegion(const std::vector& responseRegion) diff --git a/frameworks/core/components_ng/base/view_abstract.h b/frameworks/core/components_ng/base/view_abstract.h index f2552c443d2ae2ec8156c61d8484291790c8344b..d5ab3beb4a64f73f468d96b0682b3a6b121e7e64 100644 --- a/frameworks/core/components_ng/base/view_abstract.h +++ b/frameworks/core/components_ng/base/view_abstract.h @@ -422,7 +422,7 @@ public: static void SetOnAreaChanged(std::function &&onAreaChanged); static void SetOnVisibleChange(std::function &&onVisibleChange, - const std::vector &ratioList); + const std::vector &ratioList, bool enhance = false); static void SetOnSizeChanged(std::function &&onSizeChanged); static void SetResponseRegion(const std::vector &responseRegion); static void SetMouseResponseRegion(const std::vector &mouseResponseRegion); diff --git a/frameworks/core/components_ng/base/view_abstract_model.h b/frameworks/core/components_ng/base/view_abstract_model.h index 203e128765dfc48f043c9b155c812098821ff834..d1e3c0a545eb7ef5db5e053905caa26d38af577f 100644 --- a/frameworks/core/components_ng/base/view_abstract_model.h +++ b/frameworks/core/components_ng/base/view_abstract_model.h @@ -364,8 +364,8 @@ public: virtual void SetAllowDrop(const std::set& allowDrop) = 0; virtual void SetDrawModifier(const RefPtr& drawModifier) = 0; virtual void SetDragPreview(const NG::DragDropInfo& info) = 0; - virtual void SetOnVisibleChange( - std::function&& onVisibleChange, const std::vector& ratios) = 0; + virtual void SetOnVisibleChange(std::function&& onVisibleChange, + const std::vector& ratios, bool enhance = false) = 0; virtual void SetOnVisibleAreaApproximateChange(const std::function&& onVisibleChange, const std::vector& ratioList, int32_t expectedUpdateInterval) = 0; virtual void SetOnAreaChanged( diff --git a/frameworks/core/components_ng/base/view_abstract_model_ng.h b/frameworks/core/components_ng/base/view_abstract_model_ng.h index 73423db36e8fbc539bbc4bf099523dcee5d217c1..ff95fc0d5d9f89c22c98decaf6eee37f89efa212 100644 --- a/frameworks/core/components_ng/base/view_abstract_model_ng.h +++ b/frameworks/core/components_ng/base/view_abstract_model_ng.h @@ -1353,9 +1353,9 @@ public: } void SetOnVisibleChange( - std::function&& onVisibleChange, const std::vector& ratios) override + std::function&& onVisibleChange, const std::vector& ratios, bool enhance) override { - ViewAbstract::SetOnVisibleChange(std::move(onVisibleChange), ratios); + ViewAbstract::SetOnVisibleChange(std::move(onVisibleChange), ratios, enhance); } void SetOnVisibleAreaApproximateChange(const std::function&& onVisibleChange, diff --git a/frameworks/core/components_ng/event/visible_ratio_callback.h b/frameworks/core/components_ng/event/visible_ratio_callback.h index 5fdabfe0043c8e2fe9bcce71102b3de0b657beac..a0e9bd1bc825d010d06f7add4c004354e4a65a1c 100644 --- a/frameworks/core/components_ng/event/visible_ratio_callback.h +++ b/frameworks/core/components_ng/event/visible_ratio_callback.h @@ -22,11 +22,15 @@ namespace OHOS::Ace { using VisibleRatioCallback = std::function; +struct VisibleAreaOption { + bool enhance = false; +}; struct VisibleCallbackInfo { VisibleRatioCallback callback; double visibleRatio = 1.0; bool isCurrentVisible = false; uint32_t period = 0; + VisibleAreaOption option; }; } // namespace OHOS::Ace diff --git a/test/unittest/core/base/frame_node_test_ng_v3.cpp b/test/unittest/core/base/frame_node_test_ng_v3.cpp index a8874cede965ec3822f1b1e7c4114f5825766851..12cb712777a62a100d57c081b068e357a13f1ee5 100644 --- a/test/unittest/core/base/frame_node_test_ng_v3.cpp +++ b/test/unittest/core/base/frame_node_test_ng_v3.cpp @@ -474,4 +474,44 @@ HWTEST_F(FrameNodeTestNg, GetGlobalPositionOnDisplay001, TestSize.Level1) frameNode->AddChild(child); EXPECT_TRUE(frameNode->GetCurrentPageRootNode() != nullptr); } + +/** + * @tc.name: TriggerVisibleAreaChangeCallback100 + * @tc.desc: Test TriggerVisibleAreaChangeCallback. + * @tc.type: FUNC + */ +HWTEST_F(FrameNodeTestNg, TriggerVisibleAreaChangeCallback100, TestSize.Level1) +{ + /** + * @tc.steps: step1. initialize parameters. + */ + auto frameNode = FrameNode::CreateFrameNode("page", 1, AceType::MakeRefPtr(), true); + auto child = FrameNode::CreateFrameNode("column", 3, AceType::MakeRefPtr(), false); + frameNode->SetActive(true); + child->SetActive(true); + frameNode->AddChild(child); + auto context = PipelineContext::GetCurrentContext(); + ASSERT_NE(context, nullptr); + context->onShow_ = true; + frameNode->AttachContext(AceType::RawPtr(context)); + child->AttachContext(AceType::RawPtr(context)); + + RectF rect = RectF(0, 0, 100, 100); + child->renderContext_->UpdatePaintRect(rect); + frameNode->renderContext_->UpdatePaintRect(rect); + auto eventHub = child->GetOrCreateEventHub(); + ASSERT_NE(eventHub, nullptr); + auto onVisibleChange = [](bool visible, double ratio) {}; + std::vector ratioList = { 0.0, 1.0 }; + VisibleCallbackInfo addInfo; + addInfo.callback = std::move(onVisibleChange); + addInfo.isCurrentVisible = false; + child->SetVisibleAreaUserCallback(ratioList, addInfo); + auto& visibleAreaUserCallback = eventHub->GetVisibleAreaCallback(true); + child->TriggerVisibleAreaChangeCallback(1, false); + EXPECT_FALSE(visibleAreaUserCallback.option.enhance); + visibleAreaUserCallback.option = { true }; + child->TriggerVisibleAreaChangeCallback(2, false); + EXPECT_TRUE(visibleAreaUserCallback.option.enhance); +} } // namespace OHOS::Ace::NG \ No newline at end of file