!36926 修复Swiper超长显示时,快速连续滑动时,导航点显示异常问题

Merge pull request !36926 from xuzhidan/swiper_overlong_0703
This commit is contained in:
openharmony_ci 2024-07-04 14:49:47 +00:00 committed by Gitee
commit a0ba48d346
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
6 changed files with 89 additions and 34 deletions

View File

@ -2518,6 +2518,7 @@ void SwiperPattern::HandleTouchDown(const TouchLocationInfo& locationInfo)
ACE_SCOPED_TRACE("Swiper HandleTouchDown");
TAG_LOGI(AceLogTag::ACE_SWIPER, "Swiper HandleTouchDown");
isTouchDown_ = true;
isTouchDownOnOverlong_ = true;
if (HasIndicatorNode()) {
auto host = GetHost();
CHECK_NULL_VOID(host);
@ -2572,6 +2573,7 @@ void SwiperPattern::HandleTouchUp()
ACE_SCOPED_TRACE("Swiper HandleTouchUp");
TAG_LOGI(AceLogTag::ACE_SWIPER, "Swiper HandleTouchUp");
isTouchDown_ = false;
isTouchDownOnOverlong_ = false;
auto firstItemInfoInVisibleArea = GetFirstItemInfoInVisibleArea();
if (!isDragging_ && !childScrolling_ && !NearZero(firstItemInfoInVisibleArea.second.startPos) &&
!isTouchDownSpringAnimation_) {
@ -2618,6 +2620,7 @@ void SwiperPattern::HandleDragStart(const GestureEvent& info)
gestureSwipeIndex_ = currentIndex_;
isDragging_ = true;
isTouchDown_ = true;
isTouchDownOnOverlong_ = true;
mainDeltaSum_ = 0.0f;
// in drag process, close lazy feature.
SetLazyLoadFeature(false);
@ -2674,6 +2677,7 @@ void SwiperPattern::HandleDragEnd(double dragVelocity)
PerfMonitor::GetPerfMonitor()->End(PerfConstants::APP_SWIPER_SCROLL, false);
}
isTouchDown_ = false;
isTouchDownOnOverlong_ = false;
if (!CheckSwiperPanEvent(dragVelocity)) {
dragVelocity = 0.0;
}

View File

@ -710,6 +710,11 @@ public:
return isTouchDown_;
}
bool IsTouchDownOnOverlong() const
{
return isTouchDownOnOverlong_;
}
protected:
void MarkDirtyNodeSelf();
@ -1087,6 +1092,7 @@ private:
*/
bool childScrolling_ = false;
bool isTouchDown_ = false;
bool isTouchDownOnOverlong_ = false;
std::optional<bool> preLoop_;
Axis direction_ = Axis::HORIZONTAL;

View File

@ -238,9 +238,11 @@ void OverlengthDotIndicatorModifier::PlayBlackPointsAnimation(const LinearVector
}, [weak = WeakClaim(this)]() {
auto modifier = weak.Upgrade();
CHECK_NULL_VOID(modifier);
modifier->currentSelectedIndex_ = modifier->targetSelectedIndex_;
modifier->currentOverlongType_ = modifier->targetOverlongType_;
modifier->blackPointsAnimEnd_ = true;
if (!modifier->blackPointsAnimEnd_) {
modifier->currentSelectedIndex_ = modifier->targetSelectedIndex_;
modifier->currentOverlongType_ = modifier->targetOverlongType_;
modifier->blackPointsAnimEnd_ = true;
}
});
}
@ -571,6 +573,8 @@ void OverlengthDotIndicatorModifier::PlayIndicatorAnimation(const OffsetF& margi
const LinearVector<float>& itemHalfSizes, GestureState gestureState, TouchBottomTypeLoop touchBottomTypeLoop)
{
StopAnimation(false);
currentSelectedIndex_ = targetSelectedIndex_;
currentOverlongType_ = targetOverlongType_;
isTouchBottomLoop_ = false;
animationState_ = TouchBottomAnimationStage::STAGE_NONE;
normalMargin_ = margin;
@ -605,6 +609,7 @@ void OverlengthDotIndicatorModifier::StopAnimation(bool ifImmediately)
});
}
blackPointsAnimEnd_ = true;
AnimationOption option;
option.SetDuration(0);
option.SetCurve(Curves::LINEAR);
@ -621,8 +626,6 @@ void OverlengthDotIndicatorModifier::StopAnimation(bool ifImmediately)
longPointLeftAnimEnd_ = true;
longPointRightAnimEnd_ = true;
ifNeedFinishCallback_ = false;
currentSelectedIndex_ = targetSelectedIndex_;
currentOverlongType_ = targetOverlongType_;
}
void OverlengthDotIndicatorModifier::InitOverlongStatus(int32_t pageIndex)

View File

@ -171,6 +171,12 @@ public:
keepStatus_ = keepStatus;
}
void UpdateCurrentStatus()
{
currentSelectedIndex_ = targetSelectedIndex_;
currentOverlongType_ = targetOverlongType_;
}
void InitOverlongStatus(int32_t pageIndex);
void CalcTargetSelectedIndex(int32_t currentPageIndex, int32_t targetPageIndex);
void CalcTargetSelectedIndexOnForward(int32_t currentPageIndex, int32_t targetPageIndex);

View File

@ -46,6 +46,7 @@ constexpr Dimension CIRCLE_DIAMETER_OFFSET = 16.0_vp;
constexpr float INDICATOR_DRAG_MIN_ANGLE = 6.0;
constexpr float INDICATOR_DRAG_MAX_ANGLE = 23.0;
constexpr float INDICATOR_TOUCH_BOTTOM_MAX_ANGLE = 120.0;
constexpr float HALF_FLOAT = 0.5f;
} // namespace
void SwiperIndicatorPattern::OnAttachToFrameNode()
@ -1120,34 +1121,7 @@ RefPtr<OverlengthDotIndicatorPaintMethod> SwiperIndicatorPattern::CreateOverlong
auto overlongPaintMethod = MakeRefPtr<OverlengthDotIndicatorPaintMethod>(overlongDotIndicatorModifier_);
auto paintMethodTemp = DynamicCast<DotIndicatorPaintMethod>(overlongPaintMethod);
SetDotIndicatorPaintMethodInfo(swiperPattern, paintMethodTemp, swiperLayoutProperty);
overlongPaintMethod->SetMaxDisplayCount(swiperPattern->GetMaxDisplayCount());
auto animationStartIndex = swiperPattern->GetLoopIndex(swiperPattern->GetCurrentIndex());
auto animationEndIndex = swiperPattern->GetLoopIndex(swiperPattern->GetCurrentFirstIndex());
if (changeIndexWithAnimation_ && !changeIndexWithAnimation_.value()) {
animationStartIndex = overlongDotIndicatorModifier_->GetAnimationEndIndex();
paintMethodTemp->SetGestureState(GestureState::GESTURE_STATE_NONE);
}
if (jumpIndex_) {
paintMethodTemp->SetGestureState(GestureState::GESTURE_STATE_NONE);
if (!changeIndexWithAnimation_) {
overlongDotIndicatorModifier_->SetCurrentOverlongType(OverlongType::NONE);
}
}
auto isSwiperTouchDown = swiperPattern->IsTouchDown();
auto isSwiperAnimationRunning = swiperPattern->IsPropertyAnimationRunning();
auto keepStatus = !isSwiperTouchDown && !isSwiperAnimationRunning && animationStartIndex != animationEndIndex &&
!changeIndexWithAnimation_;
overlongPaintMethod->SetKeepStatus(keepStatus);
overlongPaintMethod->SetAnimationStartIndex(animationStartIndex);
overlongPaintMethod->SetAnimationEndIndex(animationEndIndex);
overlongDotIndicatorModifier_->SetIsSwiperTouchDown(isSwiperTouchDown);
overlongDotIndicatorModifier_->SetBoundsRect(CalcBoundsRect());
changeIndexWithAnimation_.reset();
jumpIndex_.reset();
UpdateOverlongPaintMethod(swiperPattern, overlongPaintMethod);
return overlongPaintMethod;
}
@ -1206,4 +1180,62 @@ RectF SwiperIndicatorPattern::CalcBoundsRect() const
return boundsRect;
}
void SwiperIndicatorPattern::UpdateOverlongPaintMethod(
const RefPtr<SwiperPattern>& swiperPattern, RefPtr<OverlengthDotIndicatorPaintMethod>& overlongPaintMethod)
{
auto animationStartIndex = swiperPattern->GetLoopIndex(swiperPattern->GetCurrentIndex());
auto animationEndIndex = swiperPattern->GetLoopIndex(swiperPattern->GetCurrentFirstIndex());
auto paintMethodTemp = DynamicCast<DotIndicatorPaintMethod>(overlongPaintMethod);
if (changeIndexWithAnimation_ && !changeIndexWithAnimation_.value()) {
animationStartIndex = overlongDotIndicatorModifier_->GetAnimationEndIndex();
paintMethodTemp->SetGestureState(GestureState::GESTURE_STATE_NONE);
}
if (jumpIndex_) {
paintMethodTemp->SetGestureState(GestureState::GESTURE_STATE_NONE);
if (!changeIndexWithAnimation_) {
overlongDotIndicatorModifier_->SetCurrentOverlongType(OverlongType::NONE);
}
}
auto isSwiperTouchDown = swiperPattern->IsTouchDownOnOverlong();
auto isSwiperAnimationRunning = swiperPattern->IsPropertyAnimationRunning();
auto keepStatus = !isSwiperTouchDown && !isSwiperAnimationRunning && animationStartIndex != animationEndIndex &&
!changeIndexWithAnimation_;
if (!changeIndexWithAnimation_ &&
(gestureState_ == GestureState::GESTURE_STATE_NONE ||
(gestureState_ == GestureState::GESTURE_STATE_FOLLOW_LEFT && !isSwiperTouchDown) ||
(gestureState_ == GestureState::GESTURE_STATE_FOLLOW_RIGHT && !isSwiperTouchDown))) {
keepStatus = true;
}
auto bottomTouchLoop = swiperPattern->GetTouchBottomTypeLoop();
auto turnPageRateAbs = std::abs(swiperPattern->GetTurnPageRate());
auto totalCount = swiperPattern->RealTotalCount();
auto loopDrag = (animationStartIndex == 0 && animationEndIndex == totalCount - 1 && turnPageRateAbs < HALF_FLOAT &&
turnPageRateAbs > 0.0f) ||
(animationStartIndex == animationEndIndex && animationEndIndex == totalCount - 1 &&
turnPageRateAbs > HALF_FLOAT);
auto nonLoopDrag = bottomTouchLoop == TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_NONE &&
((gestureState_ == GestureState::GESTURE_STATE_FOLLOW_RIGHT && turnPageRateAbs > HALF_FLOAT) ||
(gestureState_ == GestureState::GESTURE_STATE_FOLLOW_LEFT && turnPageRateAbs < HALF_FLOAT &&
turnPageRateAbs > 0.0f));
if (isSwiperTouchDown && (loopDrag || nonLoopDrag)) {
overlongDotIndicatorModifier_->UpdateCurrentStatus();
}
overlongPaintMethod->SetMaxDisplayCount(swiperPattern->GetMaxDisplayCount());
overlongPaintMethod->SetKeepStatus(keepStatus);
overlongPaintMethod->SetAnimationStartIndex(animationStartIndex);
overlongPaintMethod->SetAnimationEndIndex(animationEndIndex);
overlongDotIndicatorModifier_->SetIsSwiperTouchDown(isSwiperTouchDown);
overlongDotIndicatorModifier_->SetBoundsRect(CalcBoundsRect());
changeIndexWithAnimation_.reset();
jumpIndex_.reset();
}
} // namespace OHOS::Ace::NG

View File

@ -98,7 +98,8 @@ public:
paintMethod->SetHorizontalAndRightToLeft(swiperLayoutProperty->GetNonAutoLayoutDirection());
paintMethod->SetItemCount(swiperPattern->RealTotalCount());
paintMethod->SetDisplayCount(swiperLayoutProperty->GetDisplayCount().value_or(1));
paintMethod->SetGestureState(swiperPattern->GetGestureState());
gestureState_ = swiperPattern->GetGestureState();
paintMethod->SetGestureState(gestureState_);
paintMethod->SetTurnPageRate(swiperPattern->GetTurnPageRate());
paintMethod->SetIsLoop(swiperPattern->IsLoop());
paintMethod->SetTouchBottomTypeLoop(swiperPattern->GetTouchBottomTypeLoop());
@ -243,6 +244,8 @@ private:
RefPtr<SwiperPattern> swiperPattern);
RefPtr<DotIndicatorPaintMethod> CreateDotIndicatorPaintMethod(RefPtr<SwiperPattern> swiperPattern);
RectF CalcBoundsRect() const;
void UpdateOverlongPaintMethod(
const RefPtr<SwiperPattern>& swiperPattern, RefPtr<OverlengthDotIndicatorPaintMethod>& overlongPaintMethod);
RefPtr<ClickEvent> clickEvent_;
RefPtr<InputEvent> hoverEvent_;
@ -268,6 +271,7 @@ private:
std::optional<int32_t> jumpIndex_;
std::optional<bool> changeIndexWithAnimation_;
GestureState gestureState_ = GestureState::GESTURE_STATE_INIT;
ACE_DISALLOW_COPY_AND_MOVE(SwiperIndicatorPattern);
};
} // namespace OHOS::Ace::NG