!31006 修复List设置childrenMainSize后group大小改变没有以group内item相对List位置重新布局

Merge pull request !31006 from wind/br413
This commit is contained in:
openharmony_ci 2024-04-19 04:06:53 +00:00 committed by Gitee
commit 5c36066860
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
6 changed files with 163 additions and 54 deletions

View File

@ -106,7 +106,6 @@ void ListItemGroupLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper)
MeasureListItem(layoutWrapper, childLayoutConstraint_);
AdjustItemPosition();
AdjustByPosMap();
SetActiveChildRange(layoutWrapper);
auto crossSize = contentIdealSize.CrossSize(axis_);
if (crossSize.has_value() && GreaterOrEqualToInfinity(crossSize.value())) {
@ -132,6 +131,7 @@ float ListItemGroupLayoutAlgorithm::GetListItemGroupMaxWidth(
void ListItemGroupLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper)
{
SetActiveChildRange(layoutWrapper);
const auto& layoutProperty = layoutWrapper->GetLayoutProperty();
CHECK_NULL_VOID(layoutProperty);
auto size = layoutWrapper->GetGeometryNode()->GetFrameSize();
@ -712,7 +712,13 @@ void ListItemGroupLayoutAlgorithm::MeasureForward(LayoutWrapper* layoutWrapper,
void ListItemGroupLayoutAlgorithm::MeasureBackward(LayoutWrapper* layoutWrapper,
const LayoutConstraintF& layoutConstraint, int32_t endIndex, float endPos)
{
float currentStartPos = endPos;
float currentStartPos = childrenSize_ ? posMap_->GetPos(endIndex) + posMap_->GetRowHeight(endIndex) : endPos;
if (childrenSize_) {
float offset = referencePos_ - posMap_->GetPrevTotalHeight() + endPos - (prevEndPos_ - prevStartPos_);
float newReferencePos = endPos_ - startPos_ + offset - currentStartPos + totalMainSize_;
refPos_ = refPos_ + newReferencePos - referencePos_;
referencePos_ = newReferencePos;
}
float currentEndPos = 0.0f;
auto currentIndex = endIndex + 1;
while (GreatOrEqual(currentStartPos, startPos_ - (referencePos_ - totalMainSize_))) {
@ -739,7 +745,11 @@ void ListItemGroupLayoutAlgorithm::AdjustByPosMap()
return;
}
totalMainSize_ = posMap_->GetTotalHeight();
float offset = posMap_->GetGroupLayoutOffset(GetStartIndex(), itemPosition_.begin()->second.startPos);
float startPos = itemPosition_.begin()->second.startPos;
float offset = posMap_->GetGroupLayoutOffset(GetStartIndex(), startPos);
if (!itemPosition_.empty()) {
refPos_ -= offset;
}
for (auto& pos : itemPosition_) {
pos.second.startPos += offset;
pos.second.endPos += offset;

View File

@ -108,6 +108,12 @@ public:
endPos_ = endPos;
referencePos_ = referencePos;
forwardLayout_ = forwardLayout;
refPos_ = referencePos;
}
float GetRefPos() const
{
return refPos_;
}
void SetContentOffset(float contentStartOffset, float contentEndOffset)
@ -317,6 +323,7 @@ private:
float prevEndPos_ = 0.0f;
float endPos_ = 0.0f;
float referencePos_ = 0.0f;
float refPos_ = 0.0f;
float contentStartOffset_ = 0.0f;
float contentEndOffset_ = 0.0f;
bool forwardLayout_ = true;

View File

@ -92,6 +92,16 @@ int32_t ListLanesLayoutAlgorithm::LayoutALineForward(LayoutWrapper* layoutWrappe
bool isGroup = false;
int32_t cnt = 0;
int32_t lanes = lanes_ > 1 ? lanes_ : 1;
if (firstItemInfo_ && firstItemInfo_.value().first == currentIndex + 1) {
++currentIndex;
endPos = firstItemInfo_.value().second.endPos;
SetItemInfo(currentIndex, std::move(firstItemInfo_.value().second));
OnItemPositionAddOrUpdate(layoutWrapper, currentIndex);
firstItemInfo_.reset();
return 1;
} else if (firstItemInfo_) {
firstItemInfo_.reset();
}
for (int32_t i = 0; i < lanes && currentIndex + 1 <= GetMaxListItemIndex(); i++) {
auto wrapper = layoutWrapper->GetOrCreateChildByIndex(currentIndex + 1);
if (!wrapper) {
@ -147,6 +157,16 @@ int32_t ListLanesLayoutAlgorithm::LayoutALineBackward(LayoutWrapper* layoutWrapp
bool isGroup = false;
int32_t cnt = 0;
int32_t lanes = lanes_ > 1 ? lanes_ : 1;
if (firstItemInfo_ && firstItemInfo_.value().first == currentIndex - 1) {
--currentIndex;
startPos = firstItemInfo_.value().second.startPos;
SetItemInfo(currentIndex, std::move(firstItemInfo_.value().second));
OnItemPositionAddOrUpdate(layoutWrapper, currentIndex);
firstItemInfo_.reset();
return 1;
} else if (firstItemInfo_) {
firstItemInfo_.reset();
}
for (int32_t i = 0; i < lanes && currentIndex - 1 >= 0; i++) {
if (currentIndex > GetMaxListItemIndex() + 1) {
--currentIndex;

View File

@ -17,6 +17,7 @@
#include <algorithm>
#include <unordered_set>
#include <utility>
#include "base/geometry/axis.h"
#include "base/geometry/ng/offset_t.h"
@ -667,8 +668,42 @@ bool ListLayoutAlgorithm::CheckJumpValid(LayoutWrapper* layoutWrapper)
return true;
}
void ListLayoutAlgorithm::CheckAndMeasureStartItem(LayoutWrapper* layoutWrapper, int32_t startIndex,
float& startPos, bool isGroup, bool forwardLayout)
{
if (!isGroup || IsScrollSnapAlignCenter(layoutWrapper) ||
(forwardLayout && NonNegative(startPos)) || (!forwardLayout && LessOrEqual(startPos, contentMainSize_))) {
return;
}
auto wrapper = layoutWrapper->GetOrCreateChildByIndex(startIndex);
CHECK_NULL_VOID(wrapper);
int32_t id = wrapper->GetHostNode()->GetId();
isGroup = wrapper->GetHostTag() == V2::LIST_ITEM_GROUP_ETS_TAG;
if (!isGroup) {
return;
}
auto listLayoutProperty = AceType::DynamicCast<ListLayoutProperty>(layoutWrapper->GetLayoutProperty());
ACE_SCOPED_TRACE("ListLayoutAlgorithm::MeasureListItemGroup:%d", startIndex);
SetListItemGroupParam(wrapper, startIndex, startPos, forwardLayout, listLayoutProperty, false);
wrapper->Measure(GetGroupLayoutConstraint());
auto algorithmWrapper = wrapper->GetLayoutAlgorithm();
CHECK_NULL_VOID(algorithmWrapper);
auto itemGroup = AceType::DynamicCast<ListItemGroupLayoutAlgorithm>(algorithmWrapper->GetLayoutAlgorithm());
CHECK_NULL_VOID(itemGroup);
startPos = itemGroup->GetRefPos();
ListItemInfo itemInfo;
if (forwardLayout) {
itemInfo = { id, startPos, startPos + childrenSize_->GetChildSize(startIndex), isGroup };
} else {
itemInfo = { id, startPos - childrenSize_->GetChildSize(startIndex), startPos, isGroup };
}
firstItemInfo_ = std::make_pair(startIndex, itemInfo);
}
void ListLayoutAlgorithm::MeasureList(LayoutWrapper* layoutWrapper)
{
bool startItemIsGroup = false;
bool endItemIsGroup = false;
int32_t startIndex = 0;
int32_t endIndex = 0;
int32_t midIndex = 0;
@ -704,6 +739,8 @@ void ListLayoutAlgorithm::MeasureList(LayoutWrapper* layoutWrapper)
targetIndexStaged_ = targetIndex_;
}
if (!itemPosition_.empty()) {
startItemIsGroup = itemPosition_.begin()->second.isGroup;
endItemIsGroup = itemPosition_.rbegin()->second.isGroup;
startPos = itemPosition_.begin()->second.startPos;
endPos = itemPosition_.rbegin()->second.endPos;
itemTotalSize = endPos - startPos;
@ -764,32 +801,39 @@ void ListLayoutAlgorithm::MeasureList(LayoutWrapper* layoutWrapper)
if (IsScrollSnapAlignCenter(layoutWrapper)) {
midItemHeight = childrenSize_ ?
GetChildHeight(layoutWrapper, midIndex) : MeasureAndGetChildHeight(layoutWrapper, midIndex);
startIndex = midIndex;
endIndex = midIndex;
}
if (NearZero(currentOffset_) || (!overScrollFeature_ && NonNegative(currentOffset_)) ||
(overScrollFeature_ && overScrollTop) ||
LessOrEqual(itemTotalSize, contentMainSize_ - contentStartOffset_ - contentEndOffset_)) {
startIndex = GetLanesFloor(layoutWrapper, startIndex);
if (overScrollTop && !canOverScroll_) {
startPos = startMainPos_ + contentStartOffset_;
}
if (IsScrollSnapAlignCenter(layoutWrapper)) {
midIndex = GetLanesFloor(layoutWrapper, midIndex);
LayoutForward(layoutWrapper, midIndex, midItemMidPos - midItemHeight / 2.0f);
} else {
startIndex = GetLanesFloor(layoutWrapper, startIndex);
LayoutForward(layoutWrapper, startIndex, startPos);
startPos = midItemMidPos - midItemHeight / 2.0f;
}
if (childrenSize_) {
CheckAndMeasureStartItem(layoutWrapper, startIndex, startPos, startItemIsGroup, true);
posMap_->OptimizeBeforeMeasure(startIndex, startPos, currentOffset_, contentMainSize_);
}
LayoutForward(layoutWrapper, startIndex, startPos);
if (GetStartIndex() > 0 && GreatNotEqual(GetStartPosition(), startMainPos_)) {
LayoutBackward(layoutWrapper, GetStartIndex() - 1, GetStartPosition());
}
} else {
endIndex = GetLanesCeil(layoutWrapper, endIndex);
if (overScrollFeature_ && !overScrollTop && !NearZero(prevContentMainSize_)) {
endPos += contentMainSize_ - prevContentMainSize_;
}
if (IsScrollSnapAlignCenter(layoutWrapper)) {
endIndex = midIndex;
endPos = midItemMidPos + midItemHeight / 2.0f;
}
endIndex = GetLanesCeil(layoutWrapper, endIndex);
if (childrenSize_) {
CheckAndMeasureStartItem(layoutWrapper, endIndex, endPos, endItemIsGroup, false);
posMap_->OptimizeBeforeMeasure(endIndex, endPos, currentOffset_, contentMainSize_);
}
LayoutBackward(layoutWrapper, endIndex, endPos);
if (GetEndIndex() < (totalItemCount_ - 1) && LessNotEqual(GetEndPosition(), endMainPos_)) {
LayoutForward(layoutWrapper, GetEndIndex() + 1, GetEndPosition());
@ -804,24 +848,33 @@ int32_t ListLayoutAlgorithm::LayoutALineForward(LayoutWrapper* layoutWrapper,
if (currentIndex + 1 >= totalItemCount_) {
return 0;
}
auto wrapper = layoutWrapper->GetOrCreateChildByIndex(currentIndex + 1);
CHECK_NULL_RETURN(wrapper, 0);
int32_t id = wrapper->GetHostNode()->GetId();
++currentIndex;
bool isGroup = wrapper->GetHostTag() == V2::LIST_ITEM_GROUP_ETS_TAG;
if (isGroup) {
auto listLayoutProperty = AceType::DynamicCast<ListLayoutProperty>(layoutWrapper->GetLayoutProperty());
ACE_SCOPED_TRACE("ListLayoutAlgorithm::MeasureListItemGroup:%d", currentIndex);
SetListItemGroupParam(wrapper, currentIndex, startPos, true, listLayoutProperty, false);
wrapper->Measure(childLayoutConstraint_);
} else if (CheckNeedMeasure(wrapper)) {
ACE_SCOPED_TRACE("ListLayoutAlgorithm::MeasureListItem:%d", currentIndex);
wrapper->Measure(childLayoutConstraint_);
if (!firstItemInfo_ || firstItemInfo_.value().first != currentIndex + 1) {
auto wrapper = layoutWrapper->GetOrCreateChildByIndex(currentIndex + 1);
CHECK_NULL_RETURN(wrapper, 0);
int32_t id = wrapper->GetHostNode()->GetId();
++currentIndex;
bool isGroup = wrapper->GetHostTag() == V2::LIST_ITEM_GROUP_ETS_TAG;
if (isGroup) {
auto listLayoutProperty = AceType::DynamicCast<ListLayoutProperty>(layoutWrapper->GetLayoutProperty());
ACE_SCOPED_TRACE("ListLayoutAlgorithm::MeasureListItemGroup:%d", currentIndex);
SetListItemGroupParam(wrapper, currentIndex, startPos, true, listLayoutProperty, false);
wrapper->Measure(childLayoutConstraint_);
} else if (CheckNeedMeasure(wrapper)) {
ACE_SCOPED_TRACE("ListLayoutAlgorithm::MeasureListItem:%d", currentIndex);
wrapper->Measure(childLayoutConstraint_);
}
float mainLen = childrenSize_ ? childrenSize_->GetChildSize(currentIndex) :
GetMainAxisSize(wrapper->GetGeometryNode()->GetMarginFrameSize(), axis_);
endPos = startPos + mainLen;
itemPosition_[currentIndex] = { id, startPos, endPos, isGroup };
} else {
++currentIndex;
itemPosition_[currentIndex] = firstItemInfo_.value().second;
endPos = itemPosition_[currentIndex].endPos;
}
if (firstItemInfo_) {
firstItemInfo_.reset();
}
float mainLen = childrenSize_ ? childrenSize_->GetChildSize(currentIndex) :
GetMainAxisSize(wrapper->GetGeometryNode()->GetMarginFrameSize(), axis_);
endPos = startPos + mainLen;
itemPosition_[currentIndex] = { id, startPos, endPos, isGroup };
OnItemPositionAddOrUpdate(layoutWrapper, currentIndex);
return 1;
}
@ -832,33 +885,39 @@ int32_t ListLayoutAlgorithm::LayoutALineBackward(LayoutWrapper* layoutWrapper,
if (currentIndex - 1 < 0) {
return 0;
}
auto wrapper = layoutWrapper->GetOrCreateChildByIndex(currentIndex - 1);
CHECK_NULL_RETURN(wrapper, 0);
int32_t id = wrapper->GetHostNode()->GetId();
--currentIndex;
bool isGroup = wrapper->GetHostTag() == V2::LIST_ITEM_GROUP_ETS_TAG;
if (isGroup) {
auto listLayoutProperty = AceType::DynamicCast<ListLayoutProperty>(layoutWrapper->GetLayoutProperty());
SetListItemGroupParam(wrapper, currentIndex, endPos, false, listLayoutProperty, false);
ACE_SCOPED_TRACE("ListLayoutAlgorithm::MeasureListItemGroup:%d", currentIndex);
wrapper->Measure(childLayoutConstraint_);
} else if (CheckNeedMeasure(wrapper)) {
ACE_SCOPED_TRACE("ListLayoutAlgorithm::MeasureListItem:%d", currentIndex);
wrapper->Measure(childLayoutConstraint_);
if (!firstItemInfo_ || firstItemInfo_.value().first != currentIndex - 1) {
auto wrapper = layoutWrapper->GetOrCreateChildByIndex(currentIndex - 1);
CHECK_NULL_RETURN(wrapper, 0);
int32_t id = wrapper->GetHostNode()->GetId();
--currentIndex;
bool isGroup = wrapper->GetHostTag() == V2::LIST_ITEM_GROUP_ETS_TAG;
if (isGroup) {
auto listLayoutProperty = AceType::DynamicCast<ListLayoutProperty>(layoutWrapper->GetLayoutProperty());
SetListItemGroupParam(wrapper, currentIndex, endPos, false, listLayoutProperty, false);
ACE_SCOPED_TRACE("ListLayoutAlgorithm::MeasureListItemGroup:%d", currentIndex);
wrapper->Measure(childLayoutConstraint_);
} else if (CheckNeedMeasure(wrapper)) {
ACE_SCOPED_TRACE("ListLayoutAlgorithm::MeasureListItem:%d", currentIndex);
wrapper->Measure(childLayoutConstraint_);
}
float mainLen = childrenSize_ ? childrenSize_->GetChildSize(currentIndex) :
GetMainAxisSize(wrapper->GetGeometryNode()->GetMarginFrameSize(), axis_);
startPos = endPos - mainLen;
itemPosition_[currentIndex] = { id, startPos, endPos, isGroup };
} else {
--currentIndex;
itemPosition_[currentIndex] = firstItemInfo_.value().second;
startPos = itemPosition_[currentIndex].startPos;
}
if (firstItemInfo_) {
firstItemInfo_.reset();
}
float mainLen = childrenSize_ ? childrenSize_->GetChildSize(currentIndex) :
GetMainAxisSize(wrapper->GetGeometryNode()->GetMarginFrameSize(), axis_);
startPos = endPos - mainLen;
itemPosition_[currentIndex] = { id, startPos, endPos, isGroup };
OnItemPositionAddOrUpdate(layoutWrapper, currentIndex);
return 1;
}
void ListLayoutAlgorithm::LayoutForward(LayoutWrapper* layoutWrapper, int32_t startIndex, float startPos)
{
if (childrenSize_ && itemPosition_.empty() && !overScrollFeature_ && !jumpIndex_ && !targetIndex_) {
posMap_->OptimizeBeforeMeasure(startIndex, startPos, currentOffset_, contentMainSize_);
}
float currentEndPos = startPos;
float currentStartPos = 0.0f;
float endMainPos = overScrollFeature_ ?
@ -935,9 +994,6 @@ void ListLayoutAlgorithm::LayoutForward(LayoutWrapper* layoutWrapper, int32_t st
void ListLayoutAlgorithm::LayoutBackward(LayoutWrapper* layoutWrapper, int32_t endIndex, float endPos)
{
if (childrenSize_ && itemPosition_.empty() && !overScrollFeature_ && !jumpIndex_ && !targetIndex_) {
posMap_->OptimizeBeforeMeasure(endIndex, endPos, currentOffset_, contentMainSize_);
}
float currentStartPos = endPos;
float currentEndPos = 0.0f;
float startMainPos = overScrollFeature_ ?

View File

@ -396,9 +396,12 @@ protected:
LayoutConstraintF childLayoutConstraint_;
RefPtr<ListChildrenMainSize> childrenSize_;
RefPtr<ListPositionMap> posMap_;
std::optional<std::pair<int32_t, ListItemInfo>> firstItemInfo_;
private:
void MeasureList(LayoutWrapper* layoutWrapper);
void CheckJumpToIndex();
void CheckAndMeasureStartItem(LayoutWrapper* layoutWrapper, int32_t startIndex,
float& startPos, bool isGroup, bool forwardLayout);
std::pair<int32_t, float> RequestNewItemsForward(LayoutWrapper* layoutWrapper,
const LayoutConstraintF& layoutConstraint, int32_t startIndex, float startPos, Axis axis);

View File

@ -77,11 +77,16 @@ public:
dirty_ = LIST_NO_CHANGE;
}
float GetTotalHeight()
float GetTotalHeight() const
{
return totalHeight_;
}
float GetPrevTotalHeight() const
{
return prevTotalHeight_;
}
ListPosMapUpdate CheckPosMapUpdateRule()
{
ListPosMapUpdate flag;
@ -347,6 +352,7 @@ public:
{
totalItemCount_ = totalCount;
childrenSize_ = childrenSize;
prevTotalHeight_ = totalHeight_;
if (lanes != lanes_) {
dirty_ |= LIST_UPDATE_LANES;
lanes_ = lanes;
@ -379,9 +385,9 @@ public:
ClearDirty();
}
float GetPos(int32_t startIndex, float startPos)
float GetPos(int32_t index, float offset = 0.0f)
{
return posMap_[startIndex].mainPos - startPos;
return posMap_[index].mainPos - offset;
}
float GetGroupLayoutOffset(int32_t startIndex, float startPos)
@ -438,6 +444,12 @@ public:
return rowInfo.first;
}
float GetRowHeight(int32_t input)
{
std::pair<int32_t, float> rowInfo = GetRowEndIndexAndHeight(input);
return rowInfo.second;
}
std::pair<int32_t, float> GetRowEndIndexAndHeight(const int32_t input)
{
int32_t endIndex = input;
@ -447,7 +459,7 @@ public:
endIndex++;
}
if (endIndex == totalItemCount_ - 1) {
rowHeight = totalHeight_ - posMap_[endIndex].mainPos;
rowHeight = totalHeight_ - posMap_[endIndex].mainPos - footerSize_;
} else {
rowHeight = posMap_[endIndex + 1].mainPos - posMap_[endIndex].mainPos - space_;
}
@ -463,6 +475,7 @@ private:
int32_t curLine_ = 0;
int32_t curIndex_ = 0;
float totalHeight_ = 0.0f;
float prevTotalHeight_ = 0.0f;
float curRowHeight_ = 0.0f;
float space_ = 0.0f;
float headerSize_ = 0.0f;