From 70f7521132899a3e30dc5dca10f9e7f575cae82d Mon Sep 17 00:00:00 2001 From: yeyinglong_admin Date: Wed, 6 Mar 2024 15:50:58 +0800 Subject: [PATCH] =?UTF-8?q?ListItemGroup=E6=80=A7=E8=83=BD=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yeyinglong_admin --- .../list/list_item_group_layout_algorithm.cpp | 88 +++++++++++++------ .../list/list_item_group_layout_algorithm.h | 16 +++- .../pattern/list/list_item_group_pattern.cpp | 1 + .../pattern/list/list_item_group_pattern.h | 6 ++ 4 files changed, 79 insertions(+), 32 deletions(-) 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 8fd03501b96..f06d4c89b10 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 @@ -71,29 +71,18 @@ void ListItemGroupLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) auto layoutConstraint = layoutProperty->GetLayoutConstraint().value(); CalculateLanes(listLayoutProperty_, layoutConstraint, contentIdealSize.CrossSize(axis_), axis_); - auto itemLayoutConstraint = layoutProperty->CreateChildConstraint(); + childLayoutConstraint_ = layoutProperty->CreateChildConstraint(); isCardStyle_ = IsCardStyleForListItemGroup(layoutWrapper); if (isCardStyle_) { auto maxWidth = GetListItemGroupMaxWidth(contentConstraint.parentIdealSize, layoutProperty) - layoutProperty->CreatePaddingAndBorder().Width(); contentIdealSize.SetCrossSize(maxWidth, axis_); } - UpdateListItemConstraint(contentIdealSize, itemLayoutConstraint); - auto headerFooterLayoutConstraint = layoutProperty->CreateChildConstraint(); - headerFooterLayoutConstraint.maxSize.SetMainSize(Infinity(), axis_); + UpdateListItemConstraint(contentIdealSize, childLayoutConstraint_); + constraintChanged_ = IsConstraintChanged(layoutWrapper); referencePos_ = UpdateReferencePos(layoutProperty, forwardLayout_, referencePos_); totalItemCount_ = layoutWrapper->GetTotalChildCount() - itemStartIndex_; totalMainSize_ = layoutWrapper->GetGeometryNode()->GetPaddingSize().MainSize(axis_); - if (headerIndex_ >= 0) { - auto headerWrapper = layoutWrapper->GetOrCreateChildByIndex(headerIndex_); - headerWrapper->Measure(headerFooterLayoutConstraint); - headerMainSize_ = GetMainAxisSize(headerWrapper->GetGeometryNode()->GetMarginFrameSize(), axis_); - } - if (footerIndex_ >= 0) { - auto footerWrapper = layoutWrapper->GetOrCreateChildByIndex(footerIndex_); - footerWrapper->Measure(headerFooterLayoutConstraint); - footerMainSize_ = GetMainAxisSize(footerWrapper->GetGeometryNode()->GetMarginFrameSize(), axis_); - } spaceWidth_ = ConvertToPx(space, layoutConstraint.scaleProperty, mainPercentRefer).value_or(0); if (Negative(spaceWidth_) || GreatOrEqual(spaceWidth_, endPos_ - startPos_)) { spaceWidth_ = 0.0f; @@ -108,9 +97,11 @@ void ListItemGroupLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) spaceWidth_ = std::max(spaceWidth_, dividerSpace.value()); } } + MeasureHeaderFooter(layoutWrapper); totalMainSize_ = std::max(totalMainSize_, headerMainSize_ + footerMainSize_); - MeasureListItem(layoutWrapper, itemLayoutConstraint); + MeasureListItem(layoutWrapper, childLayoutConstraint_); AdjustItemPosition(); + SetActiveChildRange(layoutWrapper); auto crossSize = contentIdealSize.CrossSize(axis_); if (crossSize.has_value() && GreaterOrEqualToInfinity(crossSize.value())) { @@ -155,6 +146,51 @@ void ListItemGroupLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) LayoutListItem(layoutWrapper, paddingOffset, crossSize); } +void ListItemGroupLayoutAlgorithm::SyncGeometry(RefPtr& wrapper) +{ + CHECK_NULL_VOID(wrapper); + auto host = wrapper->GetHostNode(); + CHECK_NULL_VOID(host); + host->ForceSyncGeometryNode(); +} + +bool ListItemGroupLayoutAlgorithm::IsConstraintChanged(LayoutWrapper* layoutWrapper) const +{ + auto host = layoutWrapper->GetHostNode(); + CHECK_NULL_RETURN(host, false); + auto pattern = host->GetPattern(); + CHECK_NULL_RETURN(pattern, false); + return pattern->GetLayoutConstraint() != childLayoutConstraint_; +} + +void ListItemGroupLayoutAlgorithm::MeasureHeaderFooter(LayoutWrapper* layoutWrapper) +{ + const auto& layoutProperty = layoutWrapper->GetLayoutProperty(); + auto headerFooterLayoutConstraint = layoutProperty->CreateChildConstraint(); + headerFooterLayoutConstraint.maxSize.SetMainSize(Infinity(), axis_); + if (headerIndex_ >= 0) { + auto headerWrapper = layoutWrapper->GetOrCreateChildByIndex(headerIndex_); + headerWrapper->Measure(headerFooterLayoutConstraint); + headerMainSize_ = GetMainAxisSize(headerWrapper->GetGeometryNode()->GetMarginFrameSize(), axis_); + } + if (footerIndex_ >= 0) { + auto footerWrapper = layoutWrapper->GetOrCreateChildByIndex(footerIndex_); + footerWrapper->Measure(headerFooterLayoutConstraint); + footerMainSize_ = GetMainAxisSize(footerWrapper->GetGeometryNode()->GetMarginFrameSize(), axis_); + } +} + +void ListItemGroupLayoutAlgorithm::SetActiveChildRange(LayoutWrapper* layoutWrapper) +{ + if (itemPosition_.empty()) { + layoutWrapper->SetActiveChildRange(-1, -1); + return; + } + auto start = itemStartIndex_ + itemPosition_.begin()->first; + auto end = itemStartIndex_ + itemPosition_.rbegin()->first; + layoutWrapper->SetActiveChildRange(start, end); +} + void ListItemGroupLayoutAlgorithm::UpdateListItemConstraint(const OptionalSizeF& selfIdealSize, LayoutConstraintF& contentConstraint) { @@ -252,7 +288,6 @@ void ListItemGroupLayoutAlgorithm::LayoutListItemAll(LayoutWrapper* layoutWrappe void ListItemGroupLayoutAlgorithm::ClearItemPosition(LayoutWrapper* layoutWrapper) { itemPosition_.clear(); - layoutWrapper->RemoveAllChildInRenderTree(); } void ListItemGroupLayoutAlgorithm::MeasureListItem( @@ -260,7 +295,6 @@ void ListItemGroupLayoutAlgorithm::MeasureListItem( { if (totalItemCount_ <= 0) { totalMainSize_ = headerMainSize_ + footerMainSize_; - layoutWrapper->RemoveAllChildInRenderTree(); itemPosition_.clear(); return; } @@ -273,7 +307,6 @@ void ListItemGroupLayoutAlgorithm::MeasureListItem( if (needAllLayout_) { needAllLayout_ = false; itemPosition_.clear(); - layoutWrapper->RemoveAllChildInRenderTree(); LayoutListItemAll(layoutWrapper, layoutConstraint, startPos); return; } @@ -300,7 +333,6 @@ void ListItemGroupLayoutAlgorithm::MeasureListItem( endIndex = jumpIndex; } itemPosition_.clear(); - layoutWrapper->RemoveAllChildInRenderTree(); jumpIndex_.reset(); } else if (!itemPosition_.empty()) { if (itemPosition_.begin()->first > 0 || (forwardLayout_ && Negative(referencePos_))) { @@ -317,9 +349,7 @@ void ListItemGroupLayoutAlgorithm::MeasureListItem( } endIndex = std::min(GetEndIndex(), totalItemCount_ - 1); itemPosition_.clear(); - layoutWrapper->RemoveAllChildInRenderTree(); } else if (!NeedMeasureItem()) { - layoutWrapper->RemoveAllChildInRenderTree(); itemPosition_.clear(); return; } @@ -399,7 +429,7 @@ int32_t ListItemGroupLayoutAlgorithm::MeasureALineAuto(LayoutWrapper* layoutWrap if (!wrapper) { return 0; } - { + if (constraintChanged_ || wrapper->CheckNeedForceMeasureAndLayout()) { ACE_SCOPED_TRACE("ListLayoutAlgorithm::MeasureListItem:%d", currentIndex); wrapper->Measure(layoutConstraint); } @@ -419,7 +449,7 @@ int32_t ListItemGroupLayoutAlgorithm::MeasureALineCenter(LayoutWrapper* layoutWr if (!wrapper) { break; } - { + if (constraintChanged_ || wrapper->CheckNeedForceMeasureAndLayout()) { ACE_SCOPED_TRACE("ListLayoutAlgorithm::MeasureListItem:%d", currentIndex + cnt); wrapper->Measure(layoutConstraint); } @@ -449,7 +479,7 @@ int32_t ListItemGroupLayoutAlgorithm::MeasureALineForward(LayoutWrapper* layoutW } cnt++; ++currentIndex; - { + if (constraintChanged_ || wrapper->CheckNeedForceMeasureAndLayout()) { ACE_SCOPED_TRACE("ListLayoutAlgorithm::MeasureListItem:%d", currentIndex); wrapper->Measure(layoutConstraint); } @@ -477,7 +507,7 @@ int32_t ListItemGroupLayoutAlgorithm::MeasureALineBackward(LayoutWrapper* layout } --currentIndex; cnt++; - { + if (constraintChanged_ || wrapper->CheckNeedForceMeasureAndLayout()) { ACE_SCOPED_TRACE("ListLayoutAlgorithm::MeasureListItem:%d", currentIndex); wrapper->Measure(layoutConstraint); } @@ -739,7 +769,6 @@ void ListItemGroupLayoutAlgorithm::CheckRecycle( if (GreatOrEqual(pos->second.second, startPos - referencePos)) { break; } - RecycleListItem(layoutWrapper, pos->first); itemPosition_.erase(pos++); } return; @@ -749,7 +778,6 @@ void ListItemGroupLayoutAlgorithm::CheckRecycle( if (LessOrEqual(pos->second.first, endPos - (referencePos - totalMainSize_))) { break; } - RecycleListItem(layoutWrapper, pos->first); removeIndexes.emplace_back(pos->first); } for (const auto& index : removeIndexes) { @@ -782,7 +810,11 @@ void ListItemGroupLayoutAlgorithm::LayoutListItem(LayoutWrapper* layoutWrapper, } SetListItemIndex(layoutWrapper, wrapper, pos.first); wrapper->GetGeometryNode()->SetMarginFrameOffset(offset); - wrapper->Layout(); + if (wrapper->CheckNeedForceMeasureAndLayout()) { + wrapper->Layout(); + } else { + SyncGeometry(wrapper); + } } } 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 28b1e581b26..8542b37c44d 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 @@ -203,6 +203,13 @@ public: return layoutedItemInfo_; } + const LayoutConstraintF& GetLayoutConstraint() const + { + return childLayoutConstraint_; + } + + static void SyncGeometry(RefPtr& wrapper); + private: float CalculateLaneCrossOffset(float crossSize, float childCrossSize); void UpdateListItemConstraint(const OptionalSizeF& selfIdealSize, LayoutConstraintF& contentConstraint); @@ -216,10 +223,6 @@ private: { return layoutWrapper->GetOrCreateChildByIndex(index + itemStartIndex_); } - inline void RecycleListItem(const RefPtr& layoutWrapper, int32_t index) const - { - layoutWrapper->RemoveChildInRenderTree(index + itemStartIndex_); - } void CalculateLanes(const RefPtr& layoutProperty, const LayoutConstraintF& layoutConstraint, std::optional crossSizeOptional, Axis axis); @@ -244,6 +247,8 @@ private: void MeasureStart(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, int32_t startIndex); void MeasureEnd(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, int32_t startIndex); void MeasureAuto(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, int32_t startIndex); + void MeasureHeaderFooter(LayoutWrapper* layoutWrapper); + void SetActiveChildRange(LayoutWrapper* layoutWrapper); float UpdateReferencePos(RefPtr layoutProperty, bool forwardLayout, float referencePos); bool NeedMeasureItem() const; static void SetListItemIndex(const LayoutWrapper* groupLayoutWrapper, @@ -251,6 +256,7 @@ private: bool IsCardStyleForListItemGroup(const LayoutWrapper* groupLayoutWrapper); float GetListItemGroupMaxWidth(const OptionalSizeF& parentIdealSize, RefPtr layoutProperty); void AdjustItemPosition(); + bool IsConstraintChanged(LayoutWrapper* layoutWrapper) const; bool isCardStyle_ = false; int32_t headerIndex_; @@ -287,6 +293,8 @@ private: bool needAllLayout_ = false; std::optional layoutedItemInfo_; + LayoutConstraintF childLayoutConstraint_; + bool constraintChanged_ = true; }; } // 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 10d40b0ee0f..502fc3a386f 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 @@ -118,6 +118,7 @@ bool ListItemGroupPattern::OnDirtyLayoutWrapperSwap(const RefPtr& headerMainSize_ = layoutAlgorithm->GetHeaderMainSize(); footerMainSize_ = layoutAlgorithm->GetFooterMainSize(); layoutedItemInfo_ = layoutAlgorithm->GetLayoutedItemInfo(); + layoutConstraint_ = layoutAlgorithm->GetLayoutConstraint(); layouted_ = true; CheckListDirectionInCardStyle(); auto host = GetHost(); 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 6a6727989d0..5cdbc74fd02 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 @@ -170,6 +170,11 @@ public: return layouted_ && (layoutedItemInfo_.has_value() || itemTotalCount_ == 0); } + const LayoutConstraintF& GetLayoutConstraint() const + { + return layoutConstraint_; + } + private: bool IsNeedInitClickEventRecorder() const override { @@ -196,6 +201,7 @@ private: std::optional layoutedItemInfo_; bool layouted_ = false; + LayoutConstraintF layoutConstraint_; ListItemGroupLayoutAlgorithm::PositionMap itemPosition_; float spaceWidth_ = 0.0f; -- Gitee