1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_LIST_LIST_LAYOUT_ALGORITHM_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_LIST_LIST_LAYOUT_ALGORITHM_H
18 
19 #include <map>
20 #include <optional>
21 
22 #include "base/geometry/axis.h"
23 #include "base/memory/referenced.h"
24 #include "core/components_ng/layout/layout_algorithm.h"
25 #include "core/components_ng/layout/layout_wrapper.h"
26 #include "core/components_ng/pattern/list/list_layout_property.h"
27 #include "core/components_ng/pattern/list/list_position_map.h"
28 #include "core/components_v2/list/list_component.h"
29 #include "core/components_v2/list/list_properties.h"
30 
31 namespace OHOS::Ace::NG {
32 class PipelineContext;
33 class ListPositionMap;
34 
35 struct ListItemGroupLayoutInfo {
36     bool atStart = false;
37     bool atEnd = false;
38     float averageHeight = -1;
39 };
40 
41 struct ListItemInfo {
42     int32_t id;
43     float startPos;
44     float endPos;
45     bool isGroup;
46     bool isPressed = false;
47     std::optional<ListItemGroupLayoutInfo> groupInfo;
48 };
49 
50 struct ListPredictLayoutParam {
51     std::list<int32_t> items;
52     LayoutConstraintF layoutConstraint;
53 };
54 
55 struct PredictLayoutItem {
56     int32_t index;
57     int32_t forwardCacheCount;
58     int32_t backwardCacheCount;
59 };
60 
61 struct ListPredictLayoutParamV2 {
62     std::list<PredictLayoutItem> items;
63     LayoutConstraintF layoutConstraint;
64     LayoutConstraintF groupLayoutConstraint;
65 };
66 
67 enum class ScrollAutoType {
68     NOT_CHANGE = 0,
69     START,
70     END,
71 };
72 
73 enum class LayoutDirection {
74     NONE = 0,
75     FORWARD,
76     BACKWARD,
77 };
78 
79 // TextLayoutAlgorithm acts as the underlying text layout.
80 class ACE_EXPORT ListLayoutAlgorithm : public LayoutAlgorithm {
81     DECLARE_ACE_TYPE(ListLayoutAlgorithm, LayoutAlgorithm);
82 
83 public:
84     using PositionMap = std::map<int32_t, ListItemInfo>;
85     static constexpr int32_t LAST_ITEM = -1;
86 
87     ListLayoutAlgorithm() = default;
88 
89     ~ListLayoutAlgorithm() override = default;
90 
OnReset()91     void OnReset() override {}
92 
GetItemPosition()93     const PositionMap& GetItemPosition() const
94     {
95         return itemPosition_;
96     }
97 
SetItemsPosition(const PositionMap & itemPosition)98     void SetItemsPosition(const PositionMap& itemPosition)
99     {
100         itemPosition_ = itemPosition;
101     }
102 
GetRecycledItemPosition()103     const PositionMap& GetRecycledItemPosition() const
104     {
105         return recycledItemPosition_;
106     }
107 
GetCachedItemPosition()108     const PositionMap& GetCachedItemPosition() const
109     {
110         return cachedItemPosition_;
111     }
112 
113     void ClearAllItemPosition(LayoutWrapper* layoutWrapper);
114 
SetOverScrollFeature()115     void SetOverScrollFeature()
116     {
117         overScrollFeature_ = true;
118     }
119 
SetCanOverScroll(bool canOverScroll)120     void SetCanOverScroll(bool canOverScroll)
121     {
122         canOverScroll_ = canOverScroll;
123     }
124 
SetIsSpringEffect(bool isSpringEffect)125     void SetIsSpringEffect(bool isSpringEffect)
126     {
127         isSpringEffect_ = isSpringEffect;
128     }
129 
SetIndex(int32_t index)130     void SetIndex(int32_t index)
131     {
132         jumpIndex_ = index;
133     }
134 
SetTargetIndex(int32_t index)135     void SetTargetIndex(int32_t index)
136     {
137         targetIndex_ = index;
138     }
139 
SetTargetIndexInGroup(int32_t targetIndexInGroup)140     void SetTargetIndexInGroup(int32_t targetIndexInGroup)
141     {
142         targetIndexInGroup_ = targetIndexInGroup;
143     }
144 
GetTargetIndex()145     std::optional<int32_t> GetTargetIndex() const
146     {
147         return targetIndexStaged_;
148     }
149 
SetPredictSnapOffset(float predictSnapOffset)150     void SetPredictSnapOffset(float predictSnapOffset)
151     {
152         predictSnapOffset_ = predictSnapOffset;
153     }
154 
GetPredictSnapOffset()155     std::optional<float> GetPredictSnapOffset() const
156     {
157         return predictSnapOffset_;
158     }
159 
SetPredictSnapEndPosition(float predictSnapEndPos)160     void SetPredictSnapEndPosition(float predictSnapEndPos)
161     {
162         predictSnapEndPos_ = predictSnapEndPos;
163     }
164 
GetPredictSnapEndPosition()165     std::optional<float> GetPredictSnapEndPosition()
166     {
167         return predictSnapEndPos_;
168     }
169 
SetScrollSnapVelocity(float velocity)170     void SetScrollSnapVelocity(float velocity)
171     {
172         scrollSnapVelocity_ = velocity;
173     }
174 
SetIndexInGroup(int32_t index)175     void SetIndexInGroup(int32_t index)
176     {
177         jumpIndexInGroup_ = index;
178     }
179 
SetIndexAlignment(ScrollAlign align)180     void SetIndexAlignment(ScrollAlign align)
181     {
182         scrollAlign_ = align;
183     }
184 
SetCurrentDelta(float offset)185     void SetCurrentDelta(float offset)
186     {
187         currentDelta_ = offset;
188         currentOffset_ = offset;
189     }
190 
GetCurrentOffset()191     float GetCurrentOffset() const
192     {
193         return currentOffset_ + adjustOffset_;
194     }
195 
SetIsNeedCheckOffset(bool isNeedCheckOffset)196     void SetIsNeedCheckOffset(bool isNeedCheckOffset)
197     {
198         isNeedCheckOffset_ = isNeedCheckOffset;
199     }
200 
SetTotalOffset(float totalOffset)201     void SetTotalOffset(float totalOffset)
202     {
203         totalOffset_ = totalOffset;
204     }
205 
GetContentMainSize()206     float GetContentMainSize() const
207     {
208         return contentMainSize_;
209     }
210 
SetPrevContentMainSize(float mainSize)211     void SetPrevContentMainSize(float mainSize)
212     {
213         prevContentMainSize_ = mainSize;
214     }
215 
GetStartIndex()216     int32_t GetStartIndex() const
217     {
218         return itemPosition_.empty() ? -1 : itemPosition_.begin()->first;
219     }
220 
GetEndIndex()221     int32_t GetEndIndex() const
222     {
223         return itemPosition_.empty() ? -1 : itemPosition_.rbegin()->first;
224     }
225 
226     int32_t GetMidIndex(LayoutWrapper* layoutWrapper, bool usePreContentMainSize = false);
227 
GetMaxListItemIndex()228     int32_t GetMaxListItemIndex() const
229     {
230         return totalItemCount_ - 1;
231     }
232 
SetSpaceWidth(float spaceWidth)233     void SetSpaceWidth(float spaceWidth)
234     {
235         spaceWidth_ = spaceWidth;
236     }
237 
GetSpaceWidth()238     float GetSpaceWidth() const
239     {
240         return spaceWidth_;
241     }
242 
NeedEstimateOffset()243     bool NeedEstimateOffset() const
244     {
245         return needEstimateOffset_;
246     }
247 
SetContentStartOffset(float startOffset)248     void SetContentStartOffset(float startOffset)
249     {
250         contentStartOffset_ = startOffset;
251     }
252 
SetContentEndOffset(float endOffset)253     void SetContentEndOffset(float endOffset)
254     {
255         contentEndOffset_ = endOffset;
256     }
257 
GetContentStartOffset()258     float GetContentStartOffset() const
259     {
260         return contentStartOffset_;
261     }
262 
GetContentEndOffset()263     float GetContentEndOffset() const
264     {
265         return contentEndOffset_;
266     }
267 
SetPrevContentStartOffset(float prevContentStartOffset)268     void SetPrevContentStartOffset(float prevContentStartOffset)
269     {
270         prevContentStartOffset_ = prevContentStartOffset;
271     }
272 
SetPrevContentEndOffset(float prevContentEndOffset)273     void SetPrevContentEndOffset(float prevContentEndOffset)
274     {
275         prevContentEndOffset_ = prevContentEndOffset;
276     }
277 
GetStartPosition()278     float GetStartPosition() const
279     {
280         if (itemPosition_.empty()) {
281             return 0.0f;
282         }
283         if (GetStartIndex() == 0) {
284             return itemPosition_.begin()->second.startPos;
285         }
286         return itemPosition_.begin()->second.startPos - spaceWidth_;
287     }
288 
GetEndPosition()289     float GetEndPosition() const
290     {
291         if (itemPosition_.empty()) {
292             return 0.0f;
293         }
294         if (GetEndIndex() == totalItemCount_ - 1) {
295             return itemPosition_.rbegin()->second.endPos;
296         }
297         return itemPosition_.rbegin()->second.endPos + spaceWidth_;
298     }
299 
300     float GetStartPositionWithChainOffset() const;
301 
SetChainOffsetCallback(std::function<float (int32_t)> func)302     void SetChainOffsetCallback(std::function<float(int32_t)> func)
303     {
304         chainOffsetFunc_ = std::move(func);
305     }
306 
GetChainOffset(int32_t index)307     float GetChainOffset(int32_t index) const
308     {
309         return chainOffsetFunc_ ? chainOffsetFunc_(index) : 0.0f;
310     }
311 
SetChainInterval(float interval)312     void SetChainInterval(float interval)
313     {
314         chainInterval_ = interval;
315     }
316 
IsCrossMatchChild()317     bool IsCrossMatchChild() const
318     {
319         return crossMatchChild_;
320     }
321 
322     float GetChildMaxCrossSize(LayoutWrapper* layoutWrapper, Axis axis) const;
323 
324     void Measure(LayoutWrapper* layoutWrapper) override;
325 
326     void Layout(LayoutWrapper* layoutWrapper) override;
327     void UpdateOverlay(LayoutWrapper* layoutWrapper);
328 
329     void LayoutForward(LayoutWrapper* layoutWrapper, int32_t startIndex, float startPos);
330     void LayoutBackward(LayoutWrapper* layoutWrapper, int32_t endIndex, float endPos);
331 
332     void BeginLayoutForward(float startPos, LayoutWrapper* layoutWrapper);
333 
334     void BeginLayoutBackward(float startPos, LayoutWrapper* layoutWrapper);
335 
336     void HandleJumpAuto(LayoutWrapper* layoutWrapper, int32_t startIndex, int32_t endIndex);
337 
338     void HandleJumpCenter(LayoutWrapper* layoutWrapper);
339 
340     void HandleJumpStart(LayoutWrapper* layoutWrapper);
341 
342     void HandleJumpEnd(LayoutWrapper* layoutWrapper);
343 
344     bool NoNeedJump(LayoutWrapper* layoutWrapper, float startPos, float endPos,
345         int32_t startIndex, int32_t endIndex, int32_t jumpIndex, float jumpIndexStartPos);
346 
347     bool CheckNoNeedJumpListItem(LayoutWrapper* layoutWrapper, float startPos, float endPos,
348         int32_t startIndex, int32_t endIndex, int32_t jumpIndex);
349 
350     bool CheckNoNeedJumpListItemGroup(LayoutWrapper* layoutWrapper, int32_t startIndex, int32_t endIndex,
351         int32_t jumpIndex, float jumpIndexStartPos);
352 
353     virtual float MeasureAndGetChildHeight(LayoutWrapper* layoutWrapper, int32_t childIndex,
354         bool groupLayoutAll = true);
355 
GetChildHeight(LayoutWrapper * layoutWrapper,int32_t childIndex)356     virtual float GetChildHeight(LayoutWrapper* layoutWrapper, int32_t childIndex)
357     {
358         return childrenSize_->GetChildSize(childIndex);
359     }
360 
GetLanes()361     virtual int32_t GetLanes() const
362     {
363         return 1;
364     }
365 
SetLaneGutter(float laneGutter)366     void SetLaneGutter(float laneGutter)
367     {
368         laneGutter_ = laneGutter;
369     }
370 
GetLaneGutter()371     float GetLaneGutter() const
372     {
373         return laneGutter_;
374     }
375 
376     void OffScreenLayoutDirection(LayoutWrapper* layoutWrapper);
377 
GetScrollAutoType()378     ScrollAutoType GetScrollAutoType() const
379     {
380         return scrollAutoType_;
381     }
382 
383     bool CheckJumpValid(LayoutWrapper* layoutWrapper);
384 
385     float GetListGroupItemHeight(const RefPtr<LayoutWrapper>& layoutWrapper, int32_t index);
386 
387     bool JudgeInOfScreenScrollAutoType(const RefPtr<LayoutWrapper>& layoutWrapper,
388         const RefPtr<ListLayoutProperty>& layoutProperty, float topPos, float bottomPos);
389 
390     void JudgeOutOfScreenScrollAutoType(const RefPtr<LayoutWrapper>& layoutWrapper, int32_t index,
391         const RefPtr<ListLayoutProperty>& layoutProperty, int32_t indexInGroup, int32_t judgeIndex,
392         int32_t startIndex, int32_t endIndex);
393 
GetGroupLayoutConstraint()394     virtual const LayoutConstraintF& GetGroupLayoutConstraint() const
395     {
396         return childLayoutConstraint_;
397     }
398 
399     void OnItemPositionAddOrUpdate(LayoutWrapper* layoutWrapper, int32_t index);
400 
SetListChildrenMainSize(const RefPtr<ListChildrenMainSize> & childrenMainSize)401     void SetListChildrenMainSize(const RefPtr<ListChildrenMainSize>& childrenMainSize)
402     {
403         childrenSize_ = childrenMainSize;
404     }
405 
SetListPositionMap(const RefPtr<ListPositionMap> & posMap)406     void SetListPositionMap(const RefPtr<ListPositionMap>& posMap)
407     {
408         posMap_ = posMap;
409     }
410 
411     void ResetLayoutItem(LayoutWrapper* layoutWrapper);
412 
413     std::pair<int32_t, float> GetSnapStartIndexAndPos();
414 
415     std::pair<int32_t, float> GetSnapEndIndexAndPos();
416 
417 protected:
418     virtual void UpdateListItemConstraint(
419         Axis axis, const OptionalSizeF& selfIdealSize, LayoutConstraintF& contentConstraint);
420     virtual int32_t LayoutALineForward(
421         LayoutWrapper* layoutWrapper, int32_t& currentIndex, float startPos, float& endPos);
422     virtual int32_t LayoutALineBackward(
423         LayoutWrapper* layoutWrapper, int32_t& currentIndex, float endPos, float& startPos);
424     virtual float CalculateLaneCrossOffset(float crossSize, float childCrossSize);
CalculateLanes(const RefPtr<ListLayoutProperty> & layoutProperty,const LayoutConstraintF & layoutConstraint,std::optional<float> crossSizeOptional,Axis axis)425     virtual void CalculateLanes(const RefPtr<ListLayoutProperty>& layoutProperty,
426         const LayoutConstraintF& layoutConstraint, std::optional<float> crossSizeOptional, Axis axis) {};
GetLanesFloor(LayoutWrapper * layoutWrapper,int32_t index)427     virtual int32_t GetLanesFloor(LayoutWrapper* layoutWrapper, int32_t index)
428     {
429         return index;
430     }
GetLanesCeil(LayoutWrapper * layoutWrapper,int32_t index)431     virtual int32_t GetLanesCeil(LayoutWrapper* layoutWrapper, int32_t index)
432     {
433         return index;
434     }
435     virtual void SetCacheCount(LayoutWrapper* layoutWrapper, int32_t cacheCount);
436     virtual void SetActiveChildRange(LayoutWrapper* layoutWrapper, int32_t cacheStart, int32_t cacheEnd, bool show);
437 
438     void SetListItemGroupJumpIndex(const RefPtr<ListItemGroupLayoutAlgorithm>& itemGroup,
439         bool forwardLayout, int32_t index);
440     void SetListItemGroupParam(const RefPtr<LayoutWrapper>& layoutWrapper, int32_t index, float referencePos,
441         bool forwardLayout, const RefPtr<ListLayoutProperty>& layoutProperty, bool groupNeedAllLayout,
442         bool needAdjustRefPos = false);
443     static void SetListItemIndex(const RefPtr<LayoutWrapper>& layoutWrapper, int32_t index);
444     void ReMeasureListItemGroup(LayoutWrapper* layoutWrapper, bool forwardLayout);
445     void CheckListItemGroupRecycle(
446         LayoutWrapper* layoutWrapper, int32_t index, float referencePos, bool forwardLayout) const;
447     void AdjustPostionForListItemGroup(LayoutWrapper* layoutWrapper, Axis axis, int32_t index, bool forwardLayout);
SetItemInfo(int32_t index,ListItemInfo && info)448     void SetItemInfo(int32_t index, ListItemInfo&& info)
449     {
450         itemPosition_[index] = info;
451     }
SetCachedItemInfo(int32_t index,ListItemInfo && info)452     void SetCachedItemInfo(int32_t index, ListItemInfo&& info)
453     {
454         cachedItemPosition_[index] = info;
455     }
456     void LayoutItem(RefPtr<LayoutWrapper>& layoutWrapper, int32_t index, const ListItemInfo& pos,
457         int32_t& startIndex, float crossSize);
458     static void SyncGeometry(RefPtr<LayoutWrapper>& wrapper);
459     ListItemInfo GetListItemGroupPosition(const RefPtr<LayoutWrapper>& layoutWrapper, int32_t index);
460     bool CheckNeedMeasure(const RefPtr<LayoutWrapper>& layoutWrapper) const;
461     bool CheckLayoutConstraintChanged(const RefPtr<LayoutWrapper>& layoutWrapper) const;
462     void ReviseSpace(const RefPtr<ListLayoutProperty>& listLayoutProperty);
463     CachedIndexInfo GetLayoutGroupCachedCount(LayoutWrapper* layoutWrapper, const RefPtr<LayoutWrapper>& wrapper,
464         int32_t forwardCache, int32_t backwardCache, int32_t index, bool outOfView);
465     void AdjustStartPosition(const RefPtr<LayoutWrapper>& layoutWrapper, float& startPos);
466     int32_t UpdateDefaultCachedCount(const int32_t oldCachedCount, const int32_t itemCount);
467     float GetLayoutCrossAxisSize(LayoutWrapper* layoutWrapper);
468     bool IsListLanesEqual(const RefPtr<LayoutWrapper>& wrapper) const;
469 
470     Axis axis_ = Axis::VERTICAL;
471     LayoutConstraintF childLayoutConstraint_;
472     RefPtr<ListChildrenMainSize> childrenSize_;
473     RefPtr<ListPositionMap> posMap_;
474     RefPtr<ListLayoutProperty> listLayoutProperty_;
475     std::optional<std::pair<int32_t, ListItemInfo>> firstItemInfo_;
476 private:
477     void MeasureList(LayoutWrapper* layoutWrapper);
478     LayoutDirection LayoutDirectionForTargetIndex(LayoutWrapper* layoutWrapper, int startIndex);
479     void RecycleGroupItem(LayoutWrapper* layoutWrapper) const;
480     void CheckJumpToIndex();
481     void CheckAndMeasureStartItem(LayoutWrapper* layoutWrapper, int32_t startIndex,
482         float& startPos, bool isGroup, bool forwardLayout);
483 
484     std::pair<int32_t, float> RequestNewItemsForward(LayoutWrapper* layoutWrapper,
485         const LayoutConstraintF& layoutConstraint, int32_t startIndex, float startPos, Axis axis);
486 
487     std::pair<int32_t, float> RequestNewItemsBackward(LayoutWrapper* layoutWrapper,
488         const LayoutConstraintF& layoutConstraint, int32_t startIndex, float startPos, Axis axis);
489 
490     void OnSurfaceChanged(LayoutWrapper* layoutWrapper);
491 
492     void FixPredictSnapOffset(const RefPtr<ListLayoutProperty>& listLayoutProperty);
493     void FixPredictSnapOffsetAlignStart();
494     void FixPredictSnapOffsetAlignCenter();
495     void FixPredictSnapOffsetAlignEnd();
496     bool IsScrollSnapAlignCenter(LayoutWrapper* layoutWrapper);
497     bool LayoutCachedALine(LayoutWrapper* layoutWrapper, int32_t index, bool forward, float &currPos, float crossSize);
498     virtual std::list<int32_t> LayoutCachedItem(LayoutWrapper* layoutWrapper, int32_t cacheCount);
499     static void PostIdleTask(RefPtr<FrameNode> frameNode, const ListPredictLayoutParam& param);
500     static bool PredictBuildItem(RefPtr<LayoutWrapper> wrapper, const LayoutConstraintF& constraint);
501 
502     void ProcessCacheCount(LayoutWrapper* layoutWrapper, int32_t cacheCount, bool show);
503     virtual int32_t LayoutCachedForward(LayoutWrapper* layoutWrapper, int32_t cacheCount,
504         int32_t& cachedCount, int32_t curIndex, std::list<PredictLayoutItem>& predictList, bool show);
505     virtual int32_t LayoutCachedBackward(LayoutWrapper* layoutWrapper, int32_t cacheCount,
506         int32_t& cachedCount, int32_t curIndex, std::list<PredictLayoutItem>& predictList, bool show);
507     std::list<PredictLayoutItem> LayoutCachedItemV2(LayoutWrapper* layoutWrapper, int32_t cacheCount, bool show);
508     std::tuple<int32_t, int32_t, int32_t, int32_t> LayoutCachedItemInEdgeGroup(LayoutWrapper* layoutWrapper,
509         int32_t cacheCount, std::list<PredictLayoutItem>& predictList);
510     static bool PredictBuildGroup(RefPtr<LayoutWrapper> wrapper, const LayoutConstraintF& constraint, int64_t deadline,
511         int32_t forwardCached, int32_t backwardCached, const ListMainSizeValues& listMainSizeValues);
512     static void PostIdleTaskV2(RefPtr<FrameNode> frameNode, const ListPredictLayoutParamV2& param,
513         ListMainSizeValues listMainSizeValues, bool show);
514     static void PredictBuildV2(RefPtr<FrameNode> frameNode, int64_t deadline,
515         ListMainSizeValues listMainSizeValues, bool show);
516 
517     float GetStopOnScreenOffset(V2::ScrollSnapAlign scrollSnapAlign) const;
518     void FindPredictSnapIndexInItemPositionsStart(float predictEndPos, int32_t& endIndex, int32_t& currIndex) const;
519     void FindPredictSnapIndexInItemPositionsCenter(float predictEndPos, int32_t& endIndex, int32_t& currIndex) const;
520     void FindPredictSnapIndexInItemPositionsEnd(float predictEndPos, int32_t& endIndex, int32_t& currIndex) const;
521     int32_t FindPredictSnapEndIndexInItemPositions(float predictEndPos, V2::ScrollSnapAlign scrollSnapAlign);
522     bool IsUniformHeightProbably();
523     float CalculatePredictSnapEndPositionByIndex(int32_t index, V2::ScrollSnapAlign scrollSnapAlign);
524     void UpdateSnapCenterContentOffset(LayoutWrapper* layoutWrapper);
525     std::optional<ListItemGroupLayoutInfo> GetListItemGroupLayoutInfo(
526         const RefPtr<LayoutWrapper>& wrapper) const;
527     int32_t GetListItemGroupItemCount(const RefPtr<LayoutWrapper>& wrapper) const;
528 
529     std::optional<int32_t> jumpIndex_;
530     std::optional<int32_t> jumpIndexInGroup_;
531     std::optional<int32_t> targetIndex_;
532     std::optional<int32_t> targetIndexInGroup_;
533     std::optional<int32_t> targetIndexStaged_;
534     std::optional<float> predictSnapOffset_;
535     std::optional<float> predictSnapEndPos_;
536     float scrollSnapVelocity_;
537     ScrollAlign scrollAlign_ = ScrollAlign::START;
538     ScrollAutoType scrollAutoType_ = ScrollAutoType::NOT_CHANGE;
539 
540     PositionMap itemPosition_;
541     PositionMap recycledItemPosition_;
542     PositionMap cachedItemPosition_;
543     int32_t preStartIndex_ = 0;
544     float currentOffset_ = 0.0f;
545     float adjustOffset_ = 0.0f;
546     float totalOffset_ = 0.0f;
547     float currentDelta_ = 0.0f;
548     float startMainPos_ = 0.0f;
549     float endMainPos_ = 0.0f;
550     std::optional<float> layoutEndMainPos_;
551     std::optional<float> layoutStartMainPos_;
552     float contentStartOffset_ = 0.0f;
553     float contentEndOffset_ = 0.0f;
554     float prevContentStartOffset_ = 0.0f;
555     float prevContentEndOffset_ = 0.0f;
556     float spaceWidth_ = 0.0f;
557     bool overScrollFeature_ = false;
558     bool canOverScroll_ = false;
559     bool isSpringEffect_ = false;
560     bool forwardFeature_ = false;
561     bool backwardFeature_ = false;
562     bool isNeedCheckOffset_ = false;
563     bool expandSafeArea_ = false;
564 
565     int32_t totalItemCount_ = 0;
566 
567     V2::ListItemAlign listItemAlign_ = V2::ListItemAlign::START;
568 
569     bool needEstimateOffset_ = false;
570 
571     bool mainSizeIsDefined_ = false;
572     bool crossMatchChild_ = false;
573     V2::ScrollSnapAlign scrollSnapAlign_ = V2::ScrollSnapAlign::NONE;
574     bool isReverse_ = false;
575     float contentMainSize_ = 0.0f;
576     float prevContentMainSize_ = 0.0f;
577     float paddingBeforeContent_ = 0.0f;
578     float paddingAfterContent_ = 0.0f;
579     float laneGutter_ = 0.0f;
580     OffsetF paddingOffset_;
581     bool isLayouted_ = true;
582 
583     V2::StickyStyle stickyStyle_ = V2::StickyStyle::NONE;
584 
585     std::function<float(int32_t)> chainOffsetFunc_;
586     float chainInterval_ = 0.0f;
587 };
588 } // namespace OHOS::Ace::NG
589 
590 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_LIST_LIST_LAYOUT_ALGORITHM_H
591