From 4a3f53cf5b5dba4cf7add339a883c6b34e7e5e7a Mon Sep 17 00:00:00 2001 From: zhanghang Date: Tue, 19 Aug 2025 13:42:02 +0800 Subject: [PATCH] =?UTF-8?q?bugfix:=20=E4=BF=AE=E5=A4=8Dlist=E5=B5=8C?= =?UTF-8?q?=E5=A5=97listitemgroup=E8=B5=B0=E7=84=A6bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhanghang Change-Id: I6979b9b32483a473f8e96a4298a369d7bd7672d9 --- .../core/components_ng/event/focus_hub.cpp | 27 +++++++++--- .../pattern/list/list_pattern.cpp | 11 +++-- .../components_ng/pattern/list/list_pattern.h | 2 +- .../focus_hub_test_ng_branch_coverage.cpp | 42 +++++++++++++++++++ 4 files changed, 71 insertions(+), 11 deletions(-) diff --git a/frameworks/core/components_ng/event/focus_hub.cpp b/frameworks/core/components_ng/event/focus_hub.cpp index ceee76e631e..f36e73efde8 100644 --- a/frameworks/core/components_ng/event/focus_hub.cpp +++ b/frameworks/core/components_ng/event/focus_hub.cpp @@ -20,6 +20,7 @@ #include "base/utils/multi_thread.h" #include "core/components/theme/app_theme.h" #include "core/components_ng/base/inspector.h" +#include "core/components_ng/pattern/list/list_pattern.h" #include "core/components_ng/pattern/scrollable/scrollable_pattern.h" #include "core/components_ng/pattern/scrollable/scrollable_utils.h" #include "core/components_ng/token_theme/token_theme_storage.h" @@ -2153,12 +2154,26 @@ bool FocusHub::ScrollByOffsetToParent(const RefPtr& parentFrameNode) if (!scrollFunc || scrollAxis == Axis::NONE) { return false; } - MoveOffsetParam param { - scrollAxis == Axis::VERTICAL, - scrollAbility.contentStartOffset, - scrollAbility.contentEndOffset, - false - }; + MoveOffsetParam param { scrollAxis == Axis::VERTICAL, scrollAbility.contentStartOffset, + scrollAbility.contentEndOffset, false }; + if (AceType::InstanceOf(parentPattern)) { + auto listPattern = AceType::DynamicCast(parentPattern); + RefPtr parent = curFrameNode; + RefPtr listItemNode; + while (parent && parent != parentFrameNode) { + if (parent->GetTag() == V2::LIST_ITEM_ETS_TAG) { + listItemNode = AceType::DynamicCast(parent); + } + parent = parent->GetParent(); + } + if (listItemNode) { + auto listItemPattern = listItemNode->GetPattern(); + auto indexInListItemGroup = listItemPattern->GetIndexInListItemGroup(); + auto indexInList = listItemPattern->GetIndexInList(); + listPattern->LayoutListForFocus( + indexInList, indexInListItemGroup == -1 ? std::nullopt : std::optional(indexInListItemGroup)); + } + } auto moveOffset = ScrollableUtils::GetMoveOffset(parentFrameNode, curFrameNode, param); if (!NearZero(moveOffset)) { TAG_LOGI(AceLogTag::ACE_FOCUS, "Scroll offset: %{public}f on %{public}s/%{public}d, axis: %{public}d", diff --git a/frameworks/core/components_ng/pattern/list/list_pattern.cpp b/frameworks/core/components_ng/pattern/list/list_pattern.cpp index 7290db2961c..5e10bd85e74 100644 --- a/frameworks/core/components_ng/pattern/list/list_pattern.cpp +++ b/frameworks/core/components_ng/pattern/list/list_pattern.cpp @@ -3423,9 +3423,9 @@ bool ListPattern::LayoutItemInGroupForFocus(int32_t indexInList, int32_t nextInd return true; } -bool ListPattern::LayoutListForFocus(int32_t nextIndex, int32_t curIndex) +bool ListPattern::LayoutListForFocus(int32_t nextIndex, std::optional indexInGroup) { - if (!IsLayout(nextIndex, std::nullopt, ScrollAlign::AUTO)) { + if (!IsLayout(nextIndex, indexInGroup, ScrollAlign::AUTO)) { isLayoutListForFocus_ = true; targetIndex_ = nextIndex; if (nextIndex < startIndex_) { @@ -3433,6 +3433,9 @@ bool ListPattern::LayoutListForFocus(int32_t nextIndex, int32_t curIndex) } else if (nextIndex > endIndex_) { scrollAlign_ = ScrollAlign::END; } + if (indexInGroup) { + targetIndexInGroup_ = indexInGroup.value(); + } auto pipeline = GetContext(); CHECK_NULL_RETURN(pipeline, false); MarkDirtyNodeSelf(); @@ -3497,7 +3500,7 @@ int32_t ListPattern::GetNextMoveStepForMultiLanes( auto it = itemPosition_.find(loopIndex); auto itCache = cachedItemPosition_.find(loopIndex); if (it == itemPosition_.end() && itCache == cachedItemPosition_.end()) { - LayoutListForFocus(loopIndex, curIndex); + LayoutListForFocus(loopIndex, std::nullopt); it = itemPosition_.find(loopIndex); itCache = cachedItemPosition_.find(loopIndex); if (it == itemPosition_.end() && itCache == cachedItemPosition_.end()) { @@ -3545,7 +3548,7 @@ WeakPtr ListPattern::GetNextFocusNodeInList(FocusStep step, const Weak if (nextIndex == curIndex) { return nullptr; } - LayoutListForFocus(nextIndex, curIndex); + LayoutListForFocus(nextIndex, std::nullopt); auto nextFocusNode = FindChildFocusNodeByIndex(nextIndex, step, curIndex); auto isDefault = GetFocusWrapMode() == FocusWrapMode::DEFAULT; if (nextFocusNode.Upgrade()) { diff --git a/frameworks/core/components_ng/pattern/list/list_pattern.h b/frameworks/core/components_ng/pattern/list/list_pattern.h index c0058d8cfe3..713503de128 100644 --- a/frameworks/core/components_ng/pattern/list/list_pattern.h +++ b/frameworks/core/components_ng/pattern/list/list_pattern.h @@ -460,6 +460,7 @@ public: { draggingIndex_ = index; } + bool LayoutListForFocus(int32_t nextIndex, std::optional indexInGroup); protected: void OnModifyDone() override; @@ -580,7 +581,6 @@ private: const RectF& selectedZone, const RefPtr& itemGroupNode, const OffsetF& groupOffset); // focus - bool LayoutListForFocus(int32_t nextIndex, int32_t curIndex); bool IsLayout(int32_t index, std::optional indexInGroup, ScrollAlign align); int32_t GetNextMoveStepForMultiLanes(int32_t curIndex, FocusStep focuseStep, bool isVertical, int32_t& nextIndex); WeakPtr GetNextFocusNodeInList(FocusStep step, const WeakPtr& currentFocusNode); diff --git a/test/unittest/core/event/focus_hub_test_ng_branch_coverage.cpp b/test/unittest/core/event/focus_hub_test_ng_branch_coverage.cpp index e8ce63b421f..2877f6d8d1e 100644 --- a/test/unittest/core/event/focus_hub_test_ng_branch_coverage.cpp +++ b/test/unittest/core/event/focus_hub_test_ng_branch_coverage.cpp @@ -579,4 +579,46 @@ HWTEST_F(FocusHubTestNg, AcceptFocusOfSpecifyChild01, TestSize.Level1) auto res = focusHub->AcceptFocusOfSpecifyChild(FocusStep::TAB); ASSERT_TRUE(res); } + +/** + * @tc.name: ScrollByOffsetToParent001 + * @tc.desc: Test the function ScrollByOffsetToParent. + * @tc.type: FUNC + */ +HWTEST_F(FocusHubTestNg, ScrollByOffsetToParent001, TestSize.Level1) +{ + /** + * @tc.steps1: create focusHub. + */ + auto listNode = FrameNodeOnTree::CreateFrameNode( + V2::LIST_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr()); + auto listItemGroupNode = + FrameNodeOnTree::CreateFrameNode(V2::LIST_ITEM_GROUP_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), + AceType::MakeRefPtr(nullptr, V2::ListItemGroupStyle::NONE)); + auto listItemPattern = AceType::MakeRefPtr(nullptr); + auto listItemNode = FrameNodeOnTree::CreateFrameNode( + V2::LIST_ITEM_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), listItemPattern); + auto buttonNode = FrameNodeOnTree::CreateFrameNode( + V2::BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr()); + ASSERT_NE(listNode, nullptr); + ASSERT_NE(listItemGroupNode, nullptr); + ASSERT_NE(listItemPattern, nullptr); + ASSERT_NE(listItemNode, nullptr); + ASSERT_NE(buttonNode, nullptr); + buttonNode->MountToParent(listItemNode); + listItemNode->MountToParent(listItemGroupNode); + listItemGroupNode->MountToParent(listNode); + auto focusHub = buttonNode->GetOrCreateFocusHub(); + ASSERT_NE(focusHub, nullptr); + auto listPattern = listNode->GetPattern(); + ASSERT_NE(listPattern, nullptr); + EXPECT_NE(listPattern->targetIndexInGroup_, 0); + listItemPattern->indexInListItemGroup_ = 0; + + /** + * @tc.steps: step2. Set the corresponding variables to ensure entry into the target branch. + */ + focusHub->ScrollByOffsetToParent(listNode); + EXPECT_EQ(listPattern->targetIndexInGroup_, 0); +} } // namespace OHOS::Ace::NG \ No newline at end of file -- Gitee