diff --git a/frameworks/core/components_ng/pattern/grid/grid_pattern.cpp b/frameworks/core/components_ng/pattern/grid/grid_pattern.cpp index 487ea31998807045903a8db14d9f44d2b7ca870f..d0afef090eef98e366ef00bf335ddb7d9673dd9f 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_pattern.cpp +++ b/frameworks/core/components_ng/pattern/grid/grid_pattern.cpp @@ -555,6 +555,7 @@ bool GridPattern::OnDirtyLayoutWrapperSwap(const RefPtr& dirty, c CheckScrollable(); MarkSelectedItems(); isInitialized_ = true; + ChangeCanStayOverScroll(true); auto paintProperty = GetPaintProperty(); CHECK_NULL_RETURN(paintProperty, false); return paintProperty->GetFadingEdge().value_or(false) || paintProperty->HasContentClip(); diff --git a/frameworks/core/components_ng/pattern/list/list_pattern.cpp b/frameworks/core/components_ng/pattern/list/list_pattern.cpp index ede27660d3eec304700ef1630f589b47c404b43d..ef1e2562ae363b6d2b1fc7dd0b70ee3999f484fb 100644 --- a/frameworks/core/components_ng/pattern/list/list_pattern.cpp +++ b/frameworks/core/components_ng/pattern/list/list_pattern.cpp @@ -300,6 +300,7 @@ bool ListPattern::OnDirtyLayoutWrapperSwap(const RefPtr& dirty, c MarkSelectedItems(); UpdateListDirectionInCardStyle(); snapTrigByScrollBar_ = false; + ChangeCanStayOverScroll(true); return true; } diff --git a/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp b/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp index 4503bdd6c83ee8a1f40291f7beb6462ff96c5346..7b470733572a5ca03396f13f591878c743d26127 100644 --- a/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp +++ b/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp @@ -144,6 +144,7 @@ bool ScrollPattern::OnDirtyLayoutWrapperSwap(const RefPtr& dirty, if (scrollEdgeType_ != ScrollEdgeType::SCROLL_NONE && AnimateStoped()) { scrollEdgeType_ = ScrollEdgeType::SCROLL_NONE; } + ChangeCanStayOverScroll(); return paintProperty->GetFadingEdge().value_or(false); } diff --git a/frameworks/core/components_ng/pattern/scrollable/scrollable.cpp b/frameworks/core/components_ng/pattern/scrollable/scrollable.cpp index e4ef3238cb9b941c55e856b793852604c99d2bea..5b56d1b7c048d339b1e329d672ab359efbb8d422 100644 --- a/frameworks/core/components_ng/pattern/scrollable/scrollable.cpp +++ b/frameworks/core/components_ng/pattern/scrollable/scrollable.cpp @@ -628,7 +628,7 @@ void Scrollable::HandleDragStart(const OHOS::Ace::GestureEvent& info) "IsAxisAnimationRunning:%u, IsSnapAnimationRunning:%u, id:%d, tag:%s", info.GetInputEventType(), info.GetSourceTool(), isAxisEvent, IsAxisAnimationRunning(), IsSnapAnimationRunning(), nodeId_, nodeTag_.c_str()); - if (isAxisEvent) { + if (isAxisEvent && !CanStayOverScroll()) { if (!IsAxisAnimationRunning() && !IsSnapAnimationRunning()) { axisSnapDistance_ = currentPos_; snapDirection_ = SnapDirection::NONE; @@ -702,7 +702,7 @@ void Scrollable::HandleDragUpdate(const GestureEvent& info) #endif ACE_SCOPED_TRACE( "HandleDragUpdate, mainDelta:%f, source:%d, id:%d, tag:%s", mainDelta, source, nodeId_, nodeTag_.c_str()); - if (isAxisEvent) { + if (isAxisEvent && !CanStayOverScroll()) { ProcessAxisUpdateEvent(mainDelta); return; } @@ -863,6 +863,11 @@ void Scrollable::ProcessAxisEndEvent() isTouching_ = false; isDragUpdateStop_ = false; JankFrameReport::GetInstance().ClearFrameJankFlag(JANK_RUNNING_SCROLL); + if (CanStayOverScroll()) { + StopScrollable(); + HandleOverScroll(0); + SetCanStayOverScroll(false); + } } void Scrollable::ReportToDragFRCScene(double velocity, NG::SceneStatus sceneStatus) diff --git a/frameworks/core/components_ng/pattern/scrollable/scrollable_pattern.h b/frameworks/core/components_ng/pattern/scrollable/scrollable_pattern.h index 64e17ae49cb9f6e32eb39e6beb711d5d739576c2..97bbbfb3b0c876a0f709bc9bc945002ed17696bf 100644 --- a/frameworks/core/components_ng/pattern/scrollable/scrollable_pattern.h +++ b/frameworks/core/components_ng/pattern/scrollable/scrollable_pattern.h @@ -410,9 +410,9 @@ public: bool useTotalOffset = true); virtual bool CanOverScroll(int32_t source) { - auto canOverScroll = - (IsScrollableSpringEffect() && source != SCROLL_FROM_AXIS && source != SCROLL_FROM_BAR && IsScrollable() && - (!ScrollableIdle() || animateOverScroll_ || animateCanOverScroll_)); + auto canOverScroll = (IsScrollableSpringEffect() && (source != SCROLL_FROM_AXIS || GetCanStayOverScroll()) && + source != SCROLL_FROM_BAR && IsScrollable() && + (!ScrollableIdle() || animateOverScroll_ || animateCanOverScroll_)); if (canOverScroll != lastCanOverScroll_) { lastCanOverScroll_ = canOverScroll; AddScrollableFrameInfo(source); @@ -435,6 +435,12 @@ public: { return canStayOverScroll_; } + void ChangeCanStayOverScroll(bool useCurrentDelta = true) + { + if (!IsOutOfBoundary(useCurrentDelta)) { + SetIsOverScroll(false); + } + } void MarkSelectedItems(); bool ShouldSelectScrollBeStopped(); void UpdateMouseStart(float offset); diff --git a/frameworks/core/components_ng/pattern/waterflow/water_flow_pattern.cpp b/frameworks/core/components_ng/pattern/waterflow/water_flow_pattern.cpp index f44ab582c6d0a85d54cbd1c7ad95aa1a20be9ddd..d5ea0663df374a97ece9079ff6834cfc54bf0609 100644 --- a/frameworks/core/components_ng/pattern/waterflow/water_flow_pattern.cpp +++ b/frameworks/core/components_ng/pattern/waterflow/water_flow_pattern.cpp @@ -363,6 +363,7 @@ bool WaterFlowPattern::OnDirtyLayoutWrapperSwap(const RefPtr& dir } layoutInfo_->isDataValid_ = true; + ChangeCanStayOverScroll(); return NeedRender(); } diff --git a/test/unittest/core/pattern/scrollable/scrollable_test_ng.cpp b/test/unittest/core/pattern/scrollable/scrollable_test_ng.cpp index a6df6358da6124c017a216f325b7e795fddea0f3..98395904d83589a98b6b150febad38a048e993d4 100644 --- a/test/unittest/core/pattern/scrollable/scrollable_test_ng.cpp +++ b/test/unittest/core/pattern/scrollable/scrollable_test_ng.cpp @@ -1608,6 +1608,24 @@ HWTEST_F(ScrollableTestNg, onScrollerAreaChangeEventTest001, TestSize.Level1) EXPECT_EQ(isChange, true); } +/** + * @tc.name: ChangeCanStayOverScroll + * @tc.desc: Test ChangeCanStayOverScroll + * @tc.type: FUNC + */ +HWTEST_F(ScrollableTestNg, ChangeCanStayOverScroll, TestSize.Level1) +{ + /** + * @tc.steps: step1. Initialize ScrollablePattern type pointer and set EdgeEffect to Spring. + * @tc.expected: spring animation is running. + */ + auto pattern = scroll_->GetPattern(); + ASSERT_NE(pattern, nullptr); + pattern->SetCanStayOverScroll(true); + pattern->ChangeCanStayOverScroll(); + EXPECT_TRUE(pattern->GetCanStayOverScroll()); +} + #ifdef SUPPORT_DIGITAL_CROWN /** * @tc.name: ListenDigitalCrownEvent001