diff --git a/frameworks/core/components_ng/pattern/list/list_height_offset_calculator.h b/frameworks/core/components_ng/pattern/list/list_height_offset_calculator.h index 616c76b5c2c5dbddb94f651225fcbf0a2fa6daee..966c34e16e12370ee2e1d0f4f168bc40d4e82ca4 100644 --- a/frameworks/core/components_ng/pattern/list/list_height_offset_calculator.h +++ b/frameworks/core/components_ng/pattern/list/list_height_offset_calculator.h @@ -27,10 +27,11 @@ constexpr float DEFAULT_ITEM_HEIGHT = 64.f; } class ListHeightOffsetCalculator { public: - ListHeightOffsetCalculator(int32_t index, std::pair pos) + ListHeightOffsetCalculator(int32_t index, std::pair pos, float space) { targetPos_ = pos; targetIndex_ = index; + spaceWidth_ = space; } void GetFrameNodeEstimateHeightOffset(RefPtr frameNode) @@ -38,6 +39,9 @@ public: CHECK_NULL_VOID(frameNode); auto listItemPatten = frameNode->GetPattern(); if (listItemPatten) { + if (currentIndex_ > 0) { + estimateHeight_ += spaceWidth_; + } if (currentIndex_ == targetIndex_) { estimateOffset_ = estimateHeight_ - targetPos_.first; } @@ -52,6 +56,9 @@ public: } auto listItemGroupPatten = frameNode->GetPattern(); if (listItemGroupPatten) { + if (currentIndex_ > 0) { + estimateHeight_ += spaceWidth_; + } if (currentIndex_ == targetIndex_) { estimateOffset_ = listItemGroupPatten->GetEstimateOffset(estimateHeight_, targetPos_); } @@ -101,6 +108,7 @@ private: std::pair targetPos_ = { 0.0f, 0.0f }; float estimateHeight_ = 0.0f; float estimateOffset_ = 0.0f; + float spaceWidth_ = 0.0f; float totalItemHeight_ = 0.0f; float totalItemCount_ = 0.0f; diff --git a/frameworks/core/components_ng/pattern/list/list_item_group_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/list/list_item_group_layout_algorithm.cpp index 0447feec92ec6f4b5caaeab7ec63fa315478860c..4fe46adba84e3bc6351943202d49f0a425fd0b39 100644 --- a/frameworks/core/components_ng/pattern/list/list_item_group_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/list/list_item_group_layout_algorithm.cpp @@ -708,6 +708,21 @@ void ListItemGroupLayoutAlgorithm::AdjustItemPosition() } else { totalMainSize_ = std::max(totalMainSize_, GetEndPosition() + footerMainSize_); } + const auto& start = *itemPosition_.begin(); + const auto& end = *itemPosition_.rbegin(); + if (layoutedItemInfo_.has_value()) { + auto& itemInfo = layoutedItemInfo_.value(); + if (start.first <= itemInfo.startIndex || LessNotEqual(start.second.first, itemInfo.startPos)) { + itemInfo.startIndex = start.first; + itemInfo.startPos = start.second.first; + } + if (end.first >= itemInfo.endIndex || LessNotEqual(end.second.second, itemInfo.endPos)) { + itemInfo.endIndex = end.first; + itemInfo.endPos = end.second.second; + } + } else { + layoutedItemInfo_ = { start.first, start.second.first, end.first, end.second.second }; + } } void ListItemGroupLayoutAlgorithm::CheckRecycle( diff --git a/frameworks/core/components_ng/pattern/list/list_item_group_layout_algorithm.h b/frameworks/core/components_ng/pattern/list/list_item_group_layout_algorithm.h index a4df7336ba31520722d3a25900c7e770748c52a2..393f3db53093355266495c3a2a329d04a4826d0e 100644 --- a/frameworks/core/components_ng/pattern/list/list_item_group_layout_algorithm.h +++ b/frameworks/core/components_ng/pattern/list/list_item_group_layout_algorithm.h @@ -24,6 +24,12 @@ #include "core/components_v2/list/list_properties.h" namespace OHOS::Ace::NG { +struct LayoutedItemInfo { + int32_t startIndex = 0; + float startPos = 0.0f; + int32_t endIndex = 0; + float endPos = 0.0f; +}; // TextLayoutAlgorithm acts as the underlying text layout. class ACE_EXPORT ListItemGroupLayoutAlgorithm : public LayoutAlgorithm { @@ -187,6 +193,16 @@ public: return itemStartIndex_; } + void SetLayoutedItemInfo(const std::optional& itemInfo) + { + layoutedItemInfo_ = itemInfo; + } + + std::optional GetLayoutedItemInfo() const + { + return layoutedItemInfo_; + } + private: float CalculateLaneCrossOffset(float crossSize, float childCrossSize); void UpdateListItemConstraint(const OptionalSizeF& selfIdealSize, LayoutConstraintF& contentConstraint); @@ -268,6 +284,8 @@ private: float contentEndOffset_ = 0.0f; bool forwardLayout_ = true; bool needAllLayout_ = false; + + std::optional layoutedItemInfo_; }; } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/list/list_item_group_pattern.cpp b/frameworks/core/components_ng/pattern/list/list_item_group_pattern.cpp index a875c812ad1af6a44f1c8da930d3889891a5b129..af623c0db8b25e128aaa639740ff22b6ffbc7f89 100644 --- a/frameworks/core/components_ng/pattern/list/list_item_group_pattern.cpp +++ b/frameworks/core/components_ng/pattern/list/list_item_group_pattern.cpp @@ -64,6 +64,7 @@ RefPtr ListItemGroupPattern::CreateLayoutAlgorithm() { auto layoutAlgorithm = MakeRefPtr(headerIndex_, footerIndex_, itemStartIndex_); layoutAlgorithm->SetItemsPosition(itemPosition_); + layoutAlgorithm->SetLayoutedItemInfo(layoutedItemInfo_); return layoutAlgorithm; } @@ -96,6 +97,7 @@ bool ListItemGroupPattern::OnDirtyLayoutWrapperSwap(const RefPtr& itemTotalCount_ = layoutAlgorithm->GetTotalItemCount(); headerMainSize_ = layoutAlgorithm->GetHeaderMainSize(); footerMainSize_ = layoutAlgorithm->GetFooterMainSize(); + layoutedItemInfo_ = layoutAlgorithm->GetLayoutedItemInfo(); CheckListDirectionInCardStyle(); auto host = GetHost(); CHECK_NULL_RETURN(host, false); @@ -114,14 +116,15 @@ float ListItemGroupPattern::GetEstimateOffset(float height, const std::pairGetTotalChildCount(); - return averageHeight * totalItem; + if (layoutedItemInfo_.has_value()) { + auto totalHeight = (layoutedItemInfo_.value().endPos - layoutedItemInfo_.value().startPos + spaceWidth_); + auto itemCount = layoutedItemInfo_.value().endIndex - layoutedItemInfo_.value().startIndex + 1; + averageHeight = totalHeight / itemCount; + return averageHeight * itemTotalCount_ + headerMainSize_ + footerMainSize_; } - auto totalHeight = (itemPosition_.rbegin()->second.second - itemPosition_.begin()->second.first + spaceWidth_); - averageHeight = totalHeight / itemPosition_.size(); - return averageHeight * itemTotalCount_ + headerMainSize_ + footerMainSize_; + auto host = GetHost(); + auto totalItem = host->GetTotalChildCount(); + return averageHeight * totalItem; } void ListItemGroupPattern::CheckListDirectionInCardStyle() diff --git a/frameworks/core/components_ng/pattern/list/list_item_group_pattern.h b/frameworks/core/components_ng/pattern/list/list_item_group_pattern.h index 10570eece123a5a90a75c8ba4963767332ee0318..8241aca855bc7a139a7713de387773167967ab4a 100644 --- a/frameworks/core/components_ng/pattern/list/list_item_group_pattern.h +++ b/frameworks/core/components_ng/pattern/list/list_item_group_pattern.h @@ -200,6 +200,8 @@ private: float_t headerMainSize_ = 0.0f; float_t footerMainSize_ = 0.0f; + std::optional layoutedItemInfo_; + ListItemGroupLayoutAlgorithm::PositionMap itemPosition_; float spaceWidth_ = 0.0f; Axis axis_ = Axis::VERTICAL; diff --git a/frameworks/core/components_ng/pattern/list/list_pattern.cpp b/frameworks/core/components_ng/pattern/list/list_pattern.cpp index b08f4a3111388ab509c33c6f9be4192b8d964c22..2889e25bc3e24d2a911420bdf17ecafa781eeba1 100644 --- a/frameworks/core/components_ng/pattern/list/list_pattern.cpp +++ b/frameworks/core/components_ng/pattern/list/list_pattern.cpp @@ -1551,7 +1551,8 @@ void ListPattern::UpdateScrollBarOffset() auto estimatedHeight = itemsSize / itemPosition_.size() * (maxListItemIndex_ + 1) - spaceWidth_; if (lanes_ == 1) { const auto& begin = *itemPosition_.begin(); - auto calculate = ListHeightOffsetCalculator(begin.first, {begin.second.startPos, begin.second.endPos}); + auto calculate = ListHeightOffsetCalculator( + begin.first, {begin.second.startPos, begin.second.endPos}, spaceWidth_); if (calculate.GetEstimateHeightAndOffset(GetHost())) { currentOffset = calculate.GetEstimateOffset(); estimatedHeight = calculate.GetEstimateHeight();