From be38fa9d8c0f1fcc5a3cddb544be89b7788534f0 Mon Sep 17 00:00:00 2001 From: Tianer Zhou Date: Mon, 10 Jun 2024 17:24:30 +0800 Subject: [PATCH] fix fill when lane is empty Signed-off-by: Tianer Zhou Change-Id: Iee2e03bbcbd69f5fc8af1eb0d323426493d670eb --- .../sliding_window/water_flow_layout_sw.cpp | 15 +-- .../waterflow/water_flow_sw_layout_test.cpp | 92 +++++++++++++++++++ 2 files changed, 100 insertions(+), 7 deletions(-) diff --git a/frameworks/core/components_ng/pattern/waterflow/layout/sliding_window/water_flow_layout_sw.cpp b/frameworks/core/components_ng/pattern/waterflow/layout/sliding_window/water_flow_layout_sw.cpp index e705fd4f61d..18fb0414c8e 100644 --- a/frameworks/core/components_ng/pattern/waterflow/layout/sliding_window/water_flow_layout_sw.cpp +++ b/frameworks/core/components_ng/pattern/waterflow/layout/sliding_window/water_flow_layout_sw.cpp @@ -220,8 +220,8 @@ void WaterFlowLayoutSW::FillBack(float viewportBound, int32_t idx, int32_t maxCh } std::priority_queue, std::greater<>> q; for (size_t i = 0; i < info_->lanes_.size(); ++i) { - float endPos = info_->lanes_[i].endPos; - if (LessNotEqual(endPos + mainGap_, viewportBound)) { + float endPos = info_->lanes_[i].endPos + (info_->lanes_[i].items_.empty() ? 0.0f : mainGap_); + if (LessNotEqual(endPos, viewportBound)) { q.push({ endPos, i }); } } @@ -259,8 +259,8 @@ void WaterFlowLayoutSW::FillFront(float viewportBound, int32_t idx, int32_t minC } std::priority_queue, MaxHeapCmp> q; for (size_t i = 0; i < info_->lanes_.size(); ++i) { - float startPos = info_->lanes_[i].startPos; - if (GreatNotEqual(startPos - mainGap_, viewportBound)) { + float startPos = info_->lanes_[i].startPos - (info_->lanes_[i].items_.empty() ? 0.0f : mainGap_); + if (GreatNotEqual(startPos, viewportBound)) { q.push({ startPos, i }); } } @@ -305,7 +305,8 @@ void WaterFlowLayoutSW::RecoverBack(float viewportBound, int32_t& idx, int32_t m { std::unordered_set lanes; for (size_t i = 0; i < info_->lanes_.size(); ++i) { - if (LessNotEqual(info_->lanes_[i].endPos + mainGap_, viewportBound)) { + float endPos = info_->lanes_[i].endPos + (info_->lanes_[i].items_.empty() ? 0.0f : mainGap_); + if (LessNotEqual(endPos, viewportBound)) { lanes.insert(i); } } @@ -324,8 +325,8 @@ void WaterFlowLayoutSW::RecoverFront(float viewportBound, int32_t& idx, int32_t { std::unordered_set lanes; for (size_t i = 0; i < info_->lanes_.size(); ++i) { - float startPos = info_->lanes_[i].startPos; - if (GreatNotEqual(startPos - mainGap_, viewportBound)) { + float startPos = info_->lanes_[i].startPos - (info_->lanes_[i].items_.empty() ? 0.0f : mainGap_); + if (GreatNotEqual(startPos, viewportBound)) { lanes.insert(i); } } diff --git a/test/unittest/core/pattern/waterflow/water_flow_sw_layout_test.cpp b/test/unittest/core/pattern/waterflow/water_flow_sw_layout_test.cpp index cc3a98a8a7c..2844ac4dbaf 100644 --- a/test/unittest/core/pattern/waterflow/water_flow_sw_layout_test.cpp +++ b/test/unittest/core/pattern/waterflow/water_flow_sw_layout_test.cpp @@ -546,4 +546,96 @@ HWTEST_F(WaterFlowSWTest, ScrollToEdge002, TestSize.Level1) UpdateCurrentOffset(5.0f); EXPECT_FALSE(info->itemEnd_); } + +/** + * @tc.name: ScrollToEdge003 + * @tc.desc: ScrollToEdge and check overScroll + * @tc.type: FUNC + */ +HWTEST_F(WaterFlowSWTest, ScrollToEdge004, TestSize.Level1) +{ + Create([](WaterFlowModelNG model) { + model.SetFooter(GetDefaultHeaderBuilder()); + model.SetColumnsTemplate("1fr 1fr 1fr"); + model.SetRowsGap(Dimension(5.0f)); + model.SetEdgeEffect(EdgeEffect::SPRING, true); + + CreateRandomItem(100); + }); + UpdateCurrentOffset(-Infinity()); + EXPECT_EQ(GetChildY(frameNode_, 0), 750.0f); + std::vector endPos = { info_->lanes_[0].endPos, info_->lanes_[1].endPos, info_->lanes_[2].endPos }; + std::vector endItems = { info_->lanes_[0].items_.back().idx, info_->lanes_[1].items_.back().idx, + info_->lanes_[2].items_.back().idx }; + + pattern_->SetAnimateCanOverScroll(true); + info_->delta_ = -751.0f; + frameNode_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + FlushLayoutTask(frameNode_); + for (int i = 0; i < 3; ++i) { + EXPECT_EQ(info_->lanes_[i].endPos, endPos[i] - 751.0f); + if (info_->idxToLane_[99] != i) { + EXPECT_EQ(info_->lanes_[i].startPos, info_->lanes_[i].endPos); + EXPECT_TRUE(info_->lanes_[i].items_.empty()); + EXPECT_FALSE(GetChildFrameNode(frameNode_, endItems[i] + 1)->IsActive()); // + 1 to skip footer node + } else { + EXPECT_EQ(info_->lanes_[i].items_.back().idx, 99); + } + } + + const std::function canEnd = [&]() { + return std::all_of(endItems.begin(), endItems.end(), + [this](int32_t idx) { return GetChildFrameNode(frameNode_, idx)->IsActive(); }); + }; + while (!canEnd()) { + info_->delta_ = 2.0f; + frameNode_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + FlushLayoutTask(frameNode_); + for (int i = 0; i < 3; ++i) { + if (!info_->lanes_[i].items_.empty()) { + ASSERT_TRUE(GetChildFrameNode(frameNode_, endItems[i] + 1)->IsActive()); + ASSERT_EQ(GetChildRect(frameNode_, endItems[i] + 1).Bottom(), info_->lanes_[i].endPos); + } else { + ASSERT_EQ(info_->lanes_[i].startPos, info_->lanes_[i].endPos); + } + } + } +} + +/** + * @tc.name: ScrollToEdge003 + * @tc.desc: overScroll top and scroll back + * @tc.type: FUNC + */ +HWTEST_F(WaterFlowSWTest, ScrollToEdge005, TestSize.Level1) +{ + Create([](WaterFlowModelNG model) { + model.SetColumnsTemplate("1fr 1fr 1fr"); + model.SetRowsGap(Dimension(5.0f)); + model.SetEdgeEffect(EdgeEffect::SPRING, true); + + CreateRandomItem(100); + }); + pattern_->SetAnimateCanOverScroll(true); + info_->delta_ = 800.0f; + frameNode_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + FlushLayoutTask(frameNode_); + for (int i = 1; i < 3; ++i) { + EXPECT_EQ(info_->lanes_[i].startPos, 800.0f); + EXPECT_EQ(info_->lanes_[i].startPos, info_->lanes_[i].endPos); + EXPECT_TRUE(info_->lanes_[i].items_.empty()); + EXPECT_FALSE(GetChildFrameNode(frameNode_, i)->IsActive()); + } + + info_->delta_ = -2.0f; + frameNode_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + FlushLayoutTask(frameNode_); + for (int i = 0; i < 3; ++i) { + ASSERT_TRUE(GetChildFrameNode(frameNode_, i)->IsActive()); + ASSERT_EQ(GetChildY(frameNode_, i), info_->lanes_[i].startPos); + ASSERT_EQ(GetChildRect(frameNode_, i).Bottom(), + info_->lanes_[i].startPos + info_->lanes_[i].items_.front().mainSize); + ASSERT_EQ(GetChildRect(frameNode_, i).Bottom(), info_->lanes_[i].endPos); + } +} } // namespace OHOS::Ace::NG -- Gitee