From a1f7658f39af9983f3d0235c2fef2028918be7dd Mon Sep 17 00:00:00 2001 From: sichaojiang <565405659@qq.com> Date: Fri, 29 Aug 2025 16:43:02 +0800 Subject: [PATCH] =?UTF-8?q?posMap=E4=B8=8D=E5=86=8D=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=B7=B2=E7=BB=8F=E4=BC=B0=E7=AE=97=E8=BF=87=E7=9A=84=E5=80=BC?= =?UTF-8?q?=EF=BC=8C=E9=98=B2=E6=AD=A2=E5=90=8E=E7=BB=AD=E4=BC=B0=E7=AE=97?= =?UTF-8?q?=E5=AF=B9posMap=E8=BF=9B=E8=A1=8C=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I9189f69e782e5ec55e4ae69356241cc8c5062f23 Signed-off-by: sichaojiang <565405659@qq.com> --- .../list/list_height_offset_calculator.cpp | 16 +++++++--- .../pattern/list/list_pattern.cpp | 4 ++- .../pattern/list/list_position_map.cpp | 21 ++++++++++++ .../pattern/list/list_position_map.h | 3 ++ .../core/pattern/list/list_common_test_ng.cpp | 32 +++++++++++++++++++ 5 files changed, 71 insertions(+), 5 deletions(-) diff --git a/frameworks/core/components_ng/pattern/list/list_height_offset_calculator.cpp b/frameworks/core/components_ng/pattern/list/list_height_offset_calculator.cpp index b8b12c7dc7e..4c1bd06c53d 100644 --- a/frameworks/core/components_ng/pattern/list/list_height_offset_calculator.cpp +++ b/frameworks/core/components_ng/pattern/list/list_height_offset_calculator.cpp @@ -324,7 +324,9 @@ void ListHeightOffsetCalculator::CalculateLazyForEachNode(RefPtr node) if ((endIndex_ < currentIndex_) || (startIndex_ >= currentIndex_ + count)) { if (syncPosMap_ && posMap_ && (startIndex_ >= currentIndex_ + count)) { ListPositionInfo info = { estimateHeight_, estimateItemHeight_, false }; - posMap_->UpdatePosRange(currentIndex_, startIndex_, info, spaceWidth_, lanes_); + posMap_->UpdatePosRangeWithPreserve(currentIndex_, startIndex_, info, spaceWidth_, lanes_); + estimateHeight_ = posMap_->GetPositionInfo(currentIndex_ + count - 1).mainPos + + posMap_->GetPositionInfo(currentIndex_ + count - 1).mainSize; } estimateHeight_ += (estimateItemHeight_ + spaceWidth_) * GetLines(lanes_, count); if (currentIndex_ > 0) { @@ -343,11 +345,17 @@ void ListHeightOffsetCalculator::CalculateLazyForEachNode(RefPtr node) int32_t lanes = hasGroup ? 1 : lanes_; if (syncPosMap_ && posMap_) { ListPositionInfo info = { estimateHeight_, averageHeight, hasGroup }; - posMap_->UpdatePosRange(currentIndex_, startIndex_, info, spaceWidth_, lanes); + posMap_->UpdatePosRangeWithPreserve(currentIndex_, startIndex_, info, spaceWidth_, lanes); } + if (startIndex == startIndex_) { - int32_t curr = GetLines(lanes, startIndex_ - currentIndex_); - estimateOffset_ = estimateHeight_ + (averageHeight + spaceWidth_) * curr; + if (posMap_) { + estimateOffset_ = posMap_->GetPositionInfo(startIndex_ - 1).mainPos + + posMap_->GetPositionInfo(startIndex_ - 1).mainSize + spaceWidth_; + } else { + int32_t curr = GetLines(lanes, startIndex_ - currentIndex_); + estimateOffset_ = estimateHeight_ + (averageHeight + spaceWidth_) * curr; + } estimateOffset_ = CalculateOffset(node, averageHeight); } estimateHeight_ += (averageHeight + spaceWidth_) * GetLines(lanes, count) - spaceWidth_; diff --git a/frameworks/core/components_ng/pattern/list/list_pattern.cpp b/frameworks/core/components_ng/pattern/list/list_pattern.cpp index 128794b5c24..24089eb1497 100644 --- a/frameworks/core/components_ng/pattern/list/list_pattern.cpp +++ b/frameworks/core/components_ng/pattern/list/list_pattern.cpp @@ -2291,7 +2291,9 @@ float ListPattern::UpdateTotalOffset(const RefPtr& listLayo } } if (needReEstimateOffset_) { - posMap_->ClearPosMap(); + if (!isJump) { + posMap_->ClearPosMap(); + } auto calculate = ListHeightOffsetCalculator(itemPosition_, spaceWidth_, lanes_, GetAxis(), itemStartIndex_); calculate.SetPosMap(posMap_, true); calculate.GetEstimateHeightAndOffset(GetHost()); diff --git a/frameworks/core/components_ng/pattern/list/list_position_map.cpp b/frameworks/core/components_ng/pattern/list/list_position_map.cpp index 1c33e342be8..90f1468c8f1 100644 --- a/frameworks/core/components_ng/pattern/list/list_position_map.cpp +++ b/frameworks/core/components_ng/pattern/list/list_position_map.cpp @@ -27,6 +27,27 @@ void ListPositionMap::UpdatePosRange(int32_t startIndex, int32_t endIndex, } } +void ListPositionMap::UpdatePosRangeWithPreserve( + int32_t startIndex, int32_t endIndex, ListPositionInfo posInfo, float space, int32_t lanes) +{ + float currentMainPos = posInfo.mainPos; + const float originalMainSize = posInfo.mainSize; + + for (int32_t i = startIndex; i < endIndex; ++i) { + auto iter = posMap_.find(i); + if (iter != posMap_.end()) { + currentMainPos = iter->second.mainPos; + } else { + posMap_[i] = { currentMainPos, originalMainSize, posInfo.isGroup }; + } + + float usedSize = (iter != posMap_.end()) ? iter->second.mainSize : originalMainSize; + if (lanes != 0 && (i % lanes == lanes - 1)) { + currentMainPos += usedSize + space; + } + } +} + void ListPositionMap::UpdatePosWithCheck(int32_t index, ListPositionInfo posInfo) { auto iter = posMap_.find(index); diff --git a/frameworks/core/components_ng/pattern/list/list_position_map.h b/frameworks/core/components_ng/pattern/list/list_position_map.h index 0e307ba19bd..2aea6e13777 100644 --- a/frameworks/core/components_ng/pattern/list/list_position_map.h +++ b/frameworks/core/components_ng/pattern/list/list_position_map.h @@ -154,6 +154,9 @@ public: std::pair GetRowEndIndexAndHeight(const int32_t input); void ReversePosMap(); + + void UpdatePosRangeWithPreserve( + int32_t startIndex, int32_t endIndex, ListPositionInfo posInfo, float space, int32_t lanes); protected: RefPtr childrenSize_; ListChangeFlag dirty_ = LIST_NO_CHANGE; diff --git a/test/unittest/core/pattern/list/list_common_test_ng.cpp b/test/unittest/core/pattern/list/list_common_test_ng.cpp index 542eb745f1f..9c4dd2d2c19 100644 --- a/test/unittest/core/pattern/list/list_common_test_ng.cpp +++ b/test/unittest/core/pattern/list/list_common_test_ng.cpp @@ -2998,6 +2998,38 @@ HWTEST_F(ListCommonTestNg, EstimateHeight003, TestSize.Level1) } } +/** + * @tc.name: UpdatePosRangeWithPreserve001 + * @tc.desc: While updating posMap, only update the positionInfos which are not set yet + * @tc.type: FUNC + */ +HWTEST_F(ListCommonTestNg, UpdatePosRangeWithPreserve001, TestSize.Level1) +{ + ListModelNG model = CreateList(); + model.SetSpace(Dimension(SPACE)); + CreateItemsInLazyForEach(20, 60.0f); + ViewStackProcessor::GetInstance()->Pop(); + ViewStackProcessor::GetInstance()->StopGetAccessRecording(); + CreateItemsInLazyForEach(1000, 250.0f); + CreateDone(); + + ScrollToIndex(5, false, ScrollAlign::START); + auto prevInfo = pattern_->posMap_->GetPositionInfo(1); + + ScrollToIndex(900, false, ScrollAlign::START); + + // check items in the first Lazyforeach, mainSize = 60.0f + auto info = pattern_->posMap_->GetPositionInfo(1); + EXPECT_EQ(info.mainPos, prevInfo.mainPos); + EXPECT_EQ(info.mainSize, prevInfo.mainSize); + EXPECT_EQ(info.isGroup, prevInfo.isGroup); + + // check items in the second Lazyforeach, mainSize = 250.0f + info = pattern_->posMap_->GetPositionInfo(850); + EXPECT_EQ(info.mainSize, 250.0f); + EXPECT_EQ(info.isGroup, false); +} + /** * @tc.name: OnAnimateStop001 * @tc.desc: Test OnAnimateStop -- Gitee