diff --git a/frameworks/bridge/common/dom/dom_swiper.cpp b/frameworks/bridge/common/dom/dom_swiper.cpp index 4d23e422..1efee53f 100644 --- a/frameworks/bridge/common/dom/dom_swiper.cpp +++ b/frameworks/bridge/common/dom/dom_swiper.cpp @@ -26,6 +26,12 @@ namespace { constexpr uint32_t METHOD_SWIPE_TO_ARGS_SIZE = 1; constexpr double MAX_OPACITY = 255.0; constexpr double INDICATOR_POINT_SCALE = 1.33; +const std::string DISPLAY_COMPOSED_NAME = "SwiperDisplayChild"; + +std::string GetDisplayComposedId(const RefPtr& child) +{ + return "display" + std::to_string(child->GetNodeId()); +} } // namespace @@ -199,13 +205,14 @@ void DOMSwiper::OnChildNodeAdded(const RefPtr& child, int32_t slot) ACE_DCHECK(child); auto display = AceType::MakeRefPtr(child->GetRootComponent()); display->SetOpacity(MAX_OPACITY); - swiperChild_->InsertChild(slot, display); + swiperChild_->InsertChild( + slot, AceType::MakeRefPtr(GetDisplayComposedId(child), DISPLAY_COMPOSED_NAME, display)); } void DOMSwiper::OnChildNodeRemoved(const RefPtr& child) { ACE_DCHECK(child); - swiperChild_->RemoveChild(child->GetRootComponent()); + swiperChild_->RemoveChildByComposedId(GetDisplayComposedId(child)); } void DOMSwiper::PrepareSpecializedComponent() @@ -214,6 +221,12 @@ void DOMSwiper::PrepareSpecializedComponent() swiperChild_->SetIndicator(indicator_); } swiperChild_->SetShow(GetDisplay() == DisplayType::NO_SETTING || GetDisplay() == DisplayType::FLEX); + for (const auto& item : swiperChild_->GetChildren()) { + auto composedDisplay = AceType::DynamicCast(item); + if (composedDisplay) { + composedDisplay->MarkNeedUpdate(); + } + } } void DOMSwiper::ResetInitializedStyle() diff --git a/frameworks/core/components/swiper/render_swiper.cpp b/frameworks/core/components/swiper/render_swiper.cpp index 3fbd6d3e..87f4f48a 100644 --- a/frameworks/core/components/swiper/render_swiper.cpp +++ b/frameworks/core/components/swiper/render_swiper.cpp @@ -176,20 +176,6 @@ void RenderSwiper::Update(const RefPtr& component) rotationController->SetRequestRotationImpl(weak, context_); } - int32_t index = swiper->GetIndex(); - // can't change index when stretch indicator, as stretch direct is single. - if (index >= 0 && stretchRate_ == 0.0) { - if (index >= itemCount_) { - index = itemCount_ - 1; - } - if (indexInitialized) { - SwipeTo(index, false); - } else { - currentIndex_ = index; - indexInitialized = true; - } - } - childrenArray_.clear(); MarkNeedLayout(); @@ -197,7 +183,9 @@ void RenderSwiper::Update(const RefPtr& component) LOGD("swiper item is less than least slide count"); return; } + UpdateIndex(swiper->GetIndex()); Initialize(GetContext()); + isSwiperInitialized_ = isSwiperInitialized_ || swiper; } void RenderSwiper::UpdateTouchRect() @@ -255,6 +243,11 @@ void RenderSwiper::PerformLayout() } else { UpdateIndicator(); } + + if (swipeToIndex_ != -1) { + SwipeTo(swipeToIndex_, false); + swipeToIndex_ = -1; + } } void RenderSwiper::Initialize(const WeakPtr& context) @@ -402,6 +395,25 @@ void RenderSwiper::InitAccessibilityEventListener() }); } +void RenderSwiper::UpdateIndex(int32_t index) +{ + // can't change index when stretch indicator, as stretch direct is single. + if (index >= 0 && stretchRate_ == 0.0) { + if (index >= itemCount_) { + index = itemCount_ - 1; + } + if (isSwiperInitialized_) { + if (index_ != index) { + swipeToIndex_ = index; // swipe to animation need to start after perform layout + index_ = index; + } + } else { + // render node first update index + currentIndex_ = index; + } + } +} + void RenderSwiper::OnTouchTestHit( const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result) { @@ -696,6 +708,7 @@ void RenderSwiper::MoveItems(double dragOffset, int32_t fromIndex, int32_t toInd controller_->RemoveInterpolator(translate_); isAnimationAlreadyAdded_ = false; } + isIndicatorAnimationStart_ = true; double start = dragOffset; double end; @@ -1121,8 +1134,8 @@ void RenderSwiper::UpdateScrollPosition(double dragDelta) } else { toIndex = needReverse_ ? GetPrevIndex() : GetNextIndex(); } - if (toIndex < 0 || toIndex >= itemCount_) { - LOGD("toIndex is out %{public}d", toIndex); + if (toIndex < 0 || toIndex >= itemCount_ || currentIndex_ == toIndex) { + LOGD("toIndex is error %{public}d", toIndex); return; } @@ -1163,7 +1176,6 @@ void RenderSwiper::UpdateScrollPosition(double dragDelta) void RenderSwiper::UpdateChildPosition(double offset, int32_t fromIndex, int32_t toIndex) { - scrollOffset_ = offset; int32_t childrenCount = static_cast(childrenArray_.size()); if (fromIndex < 0 || fromIndex >= childrenCount || toIndex < 0 || toIndex >= childrenCount || fromIndex == toIndex) { @@ -1171,6 +1183,7 @@ void RenderSwiper::UpdateChildPosition(double offset, int32_t fromIndex, int32_t fromIndex, childrenCount); return; } + scrollOffset_ = offset; const auto& fromItem = childrenArray_[fromIndex]; fromItem->SetPosition(GetMainAxisOffset(offset)); const auto& toItem = childrenArray_[toIndex]; diff --git a/frameworks/core/components/swiper/render_swiper.h b/frameworks/core/components/swiper/render_swiper.h index de9749b3..2d5be033 100644 --- a/frameworks/core/components/swiper/render_swiper.h +++ b/frameworks/core/components/swiper/render_swiper.h @@ -298,6 +298,7 @@ private: void InitDragRecognizer(); void InitRawDragRecognizer(); void InitAccessibilityEventListener(); + void UpdateIndex(int32_t index); void MoveItems(double dragOffset, int32_t fromIndex, int32_t toIndex); void RestoreAutoPlay() { @@ -375,7 +376,9 @@ private: bool loop_ = true; bool slideContinued_ = false; bool disableSwipe_ = false; - bool indexInitialized = false; + int32_t index_ = 0; + int32_t swipeToIndex_ = -1; + bool isSwiperInitialized_ = false; // need timer for auto play RefPtr scheduler_; diff --git a/frameworks/core/pipeline/base/component_group.h b/frameworks/core/pipeline/base/component_group.h index b44c7e31..79c88c67 100644 --- a/frameworks/core/pipeline/base/component_group.h +++ b/frameworks/core/pipeline/base/component_group.h @@ -81,6 +81,21 @@ public: return; } + virtual void RemoveChildByComposedId(const ComposeId& composeId) + { + for (const auto& item : children_) { + auto compose = AceType::DynamicCast(item); + if (compose && composeId == compose->GetId()) { + auto child = compose->GetChild(); + if (child) { + child->SetParent(nullptr); + } + children_.remove(item); + return; + } + } + } + virtual void RemoveChild(const RefPtr& child) { if (!child) {