diff --git a/frameworks/core/components_ng/pattern/swiper/swiper_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/swiper/swiper_layout_algorithm.cpp index 7e296252622f269683f1c35b4dcf6c765a89cd08..4ad689ef247638507b591b301bad9ba73e9c08bc 100644 --- a/frameworks/core/components_ng/pattern/swiper/swiper_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/swiper/swiper_layout_algorithm.cpp @@ -61,9 +61,13 @@ void SwiperLayoutAlgorithm::LoadItemWithDrag(float translateLength) } int32_t nextIndex = currentIndex_; + int32_t prevMarginCount = Positive(prevMargin_) ? 1 : 0; + int32_t nextMarginCount = Positive(nextMargin_) ? 1 : 0; + auto loadItems = static_cast(floorf(fabsf(currentOffset_) / translateLength)); do { - nextIndex = Positive(currentOffset_) ? (nextIndex - 1) : (nextIndex + displayCount_); + nextIndex = Positive(currentOffset_) ? (nextIndex - 1 - prevMarginCount) : + (nextIndex + displayCount_ + nextMarginCount); AddToItemRange(nextIndex); loadItems--; } while (loadItems >= 0); @@ -126,7 +130,7 @@ void SwiperLayoutAlgorithm::InitItemRange(LayoutWrapper* layoutWrapper) CHECK_NULL_VOID(layoutWrapper); auto layoutProperty = AceType::DynamicCast(layoutWrapper->GetLayoutProperty()); CHECK_NULL_VOID(layoutProperty); - + auto cacheCount = layoutProperty->GetCachedCount().value_or(1); // If display mode is AutoLinear, expand all children. if (!SwiperUtils::IsStretch(layoutProperty)) { startIndex_ = 0; @@ -150,7 +154,7 @@ void SwiperLayoutAlgorithm::InitItemRange(LayoutWrapper* layoutWrapper) /* Load next index while dragging */ LoadItemWithDrag(translateLength); } - + CalculateIncludeMarginCacheRange(cacheCount); if (startIndex_ <= endIndex_) { for (auto index = startIndex_; index <= endIndex_; ++index) { itemRange_.insert(index); @@ -570,12 +574,16 @@ void SwiperLayoutAlgorithm::SortItems(std::list& preItems, std::list(itemRange_.size()); displayCount = std::clamp(displayCount, 0, itemCount); - auto cacheCount = static_cast(ceilf(static_cast(itemCount - displayCount) / 2.0f)); + auto cacheCount = static_cast(ceilf(static_cast(itemCount - TotalDisplayCount()) / 2.0f)); + cacheCount = std::max(0, cacheCount); auto loopIndex = (currentIndex_ - 1 + totalCount_) % totalCount_; int32_t prevTargetIndex = CaculatePrevTargetIndex(); int32_t nextTargetIndex = CaculateNextTargetIndex(); + int32_t prevMarginCount = Positive(prevMargin_) ? 1 : 0; + int32_t nextMarginCount = Positive(nextMargin_) ? 1 : 0; + int32_t count = 0; - while (itemRange_.find(loopIndex) != itemRange_.end() && count < cacheCount) { + while (itemRange_.find(loopIndex) != itemRange_.end() && count < (prevMarginCount + cacheCount)) { if (NearEqual(loopIndex, nextTargetIndex)) { break; } @@ -586,7 +594,7 @@ void SwiperLayoutAlgorithm::SortItems(std::list& preItems, std::listLayout(); } +void SwiperLayoutAlgorithm::CalculateIncludeMarginCacheRange(int32_t cacheCount) +{ + auto loadCount = cacheCount * 2 + displayCount_; + if (Positive(static_cast(prevMargin_))) { + startIndex_ = isLoop_ ? (startIndex_ - 1 + totalCount_) % totalCount_ : + std::max(startIndex_ - 1, 0); + loadCount++; + } + + if (Positive(static_cast(nextMargin_))) { + endIndex_ = isLoop_ ? (endIndex_ + 1 + totalCount_) % totalCount_ : + std::min(endIndex_ + 1, totalCount_ - 1); + loadCount++; + } + + if (GreatOrEqual(loadCount, totalCount_)) { + startIndex_ = 0; + endIndex_ = totalCount_ - 1; + } +} + int32_t SwiperLayoutAlgorithm::CaculatePrevTargetIndex() const { int32_t totalDisplayCount = TotalDisplayCount(); diff --git a/frameworks/core/components_ng/pattern/swiper/swiper_layout_algorithm.h b/frameworks/core/components_ng/pattern/swiper/swiper_layout_algorithm.h index 46dd161b63c33768fce91a6ae40b0e8ddbd3eb3d..74e5724d57efd6777691d2f77eb018023a418fae 100644 --- a/frameworks/core/components_ng/pattern/swiper/swiper_layout_algorithm.h +++ b/frameworks/core/components_ng/pattern/swiper/swiper_layout_algorithm.h @@ -135,6 +135,7 @@ private: RefPtr GetNodeLayoutWrapperByTag(LayoutWrapper* layoutWrapper, const std::string& tagName) const; void MeasureArrow(const RefPtr& arrowWrapper, const RefPtr& layoutProperty) const; void ArrowLayout(LayoutWrapper* layoutWrapper, const RefPtr& arrowWrapper) const; + void CalculateIncludeMarginCacheRange(int32_t cacheCount); int32_t CaculatePrevTargetIndex() const; int32_t CaculateNextTargetIndex() const; bool isLoop_ = true;