1 /*
2 * Copyright (c) 2022-2023 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 #include "core/components_ng/pattern/tabs/tabs_pattern.h"
17
18 #include "base/geometry/axis.h"
19 #include "base/geometry/dimension.h"
20 #include "base/utils/utils.h"
21 #include "core/common/recorder/event_recorder.h"
22 #include "core/common/recorder/node_data_cache.h"
23 #include "core/components/common/layout/constants.h"
24 #include "core/components/tab_bar/tabs_event.h"
25 #include "core/components_ng/pattern/divider/divider_layout_property.h"
26 #include "core/components_ng/pattern/divider/divider_render_property.h"
27 #include "core/components_ng/pattern/swiper/swiper_event_hub.h"
28 #include "core/components_ng/pattern/swiper/swiper_model.h"
29 #include "core/components_ng/pattern/swiper/swiper_pattern.h"
30 #include "core/components_ng/pattern/tabs/tab_bar_layout_property.h"
31 #include "core/components_ng/pattern/tabs/tab_bar_paint_property.h"
32 #include "core/components_ng/pattern/tabs/tab_bar_pattern.h"
33 #include "core/components_ng/pattern/tabs/tabs_layout_property.h"
34 #include "core/components_ng/pattern/tabs/tabs_node.h"
35 #include "core/components_ng/property/property.h"
36 #include "core/components_v2/inspector/inspector_constants.h"
37 #include "core/pipeline_ng/pipeline_context.h"
38
39 namespace OHOS::Ace::NG {
40 namespace {
41 constexpr int32_t CHILDREN_MIN_SIZE = 2;
42 } // namespace
43
OnAttachToFrameNode()44 void TabsPattern::OnAttachToFrameNode()
45 {
46 auto host = GetHost();
47 CHECK_NULL_VOID(host);
48 host->GetRenderContext()->SetClipToFrame(true);
49 // expand to navigation bar by default
50 host->GetLayoutProperty()->UpdateSafeAreaExpandOpts(
51 { .type = SAFE_AREA_TYPE_SYSTEM, .edges = SAFE_AREA_EDGE_BOTTOM });
52 }
53
SetOnChangeEvent(std::function<void (const BaseEventInfo *)> && event)54 void TabsPattern::SetOnChangeEvent(std::function<void(const BaseEventInfo*)>&& event)
55 {
56 auto tabsNode = AceType::DynamicCast<TabsNode>(GetHost());
57 CHECK_NULL_VOID(tabsNode);
58 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
59 CHECK_NULL_VOID(tabBarNode);
60 auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>();
61 CHECK_NULL_VOID(tabBarPattern);
62 auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
63 CHECK_NULL_VOID(swiperNode);
64
65 ChangeEvent changeEvent([weak = WeakClaim(this), tabBarNode, tabBarPattern, jsEvent = std::move(event)](
66 int32_t index) {
67 if (tabBarPattern->IsMaskAnimationExecuted()) {
68 return;
69 }
70 auto tabsNode = AceType::DynamicCast<TabsNode>(tabBarNode->GetParent());
71 CHECK_NULL_VOID(tabsNode);
72 auto tabsLayoutProperty = tabsNode->GetLayoutProperty<TabsLayoutProperty>();
73 CHECK_NULL_VOID(tabsLayoutProperty);
74 tabsLayoutProperty->UpdateIndex(index);
75 tabBarPattern->ResetIndicatorAnimationState();
76 auto tabBarLayoutProperty = tabBarPattern->GetLayoutProperty<TabBarLayoutProperty>();
77 CHECK_NULL_VOID(tabBarLayoutProperty);
78 if (!tabBarPattern->IsMaskAnimationByCreate()) {
79 tabBarPattern->HandleBottomTabBarChange(index);
80 }
81 tabBarPattern->SetMaskAnimationByCreate(false);
82 tabBarPattern->SetIndicator(index);
83 tabBarPattern->UpdateIndicator(index);
84 tabBarPattern->UpdateTextColorAndFontWeight(index);
85 if (tabBarLayoutProperty->GetTabBarMode().value_or(TabBarMode::FIXED) == TabBarMode::SCROLLABLE) {
86 if (tabBarPattern->GetTabBarStyle() == TabBarStyle::SUBTABBATSTYLE &&
87 tabBarLayoutProperty->GetAxisValue(Axis::HORIZONTAL) == Axis::HORIZONTAL) {
88 if (!tabBarPattern->GetChangeByClick()) {
89 tabBarPattern->PlayTabBarTranslateAnimation(index);
90 tabBarNode->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
91 } else {
92 tabBarPattern->SetChangeByClick(false);
93 }
94 } else {
95 tabBarNode->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
96 }
97 }
98 /* js callback */
99 if (jsEvent && tabsNode->IsOnMainTree()) {
100 if (Recorder::EventRecorder::Get().IsComponentRecordEnable() && weak.Upgrade()) {
101 auto inspectorId = tabsNode->GetInspectorId().value_or("");
102 auto pattern = weak.Upgrade();
103 auto tabBarText = pattern->GetTabBarTextByIndex(index);
104 Recorder::EventParamsBuilder builder;
105 builder.SetId(inspectorId)
106 .SetType(tabsNode->GetTag())
107 .SetIndex(index)
108 .SetText(tabBarText)
109 .SetDescription(tabsNode->GetAutoEventParamValue(""));
110 Recorder::EventRecorder::Get().OnChange(std::move(builder));
111 if (!inspectorId.empty()) {
112 Recorder::NodeDataCache::Get().PutMultiple(inspectorId, tabBarText, index);
113 }
114 }
115 TabContentChangeEvent eventInfo(index);
116 jsEvent(&eventInfo);
117 }
118 });
119
120 if (onChangeEvent_) {
121 (*onChangeEvent_).swap(changeEvent);
122 } else {
123 onChangeEvent_ = std::make_shared<ChangeEvent>(changeEvent);
124 auto eventHub = swiperNode->GetEventHub<SwiperEventHub>();
125 CHECK_NULL_VOID(eventHub);
126 eventHub->AddOnChangeEvent(onChangeEvent_);
127 }
128 }
129
GetTabBarTextByIndex(int32_t index) const130 std::string TabsPattern::GetTabBarTextByIndex(int32_t index) const
131 {
132 auto tabsNode = AceType::DynamicCast<TabsNode>(GetHost());
133 CHECK_NULL_RETURN(tabsNode, "");
134 auto tabBar = tabsNode->GetTabBar();
135 CHECK_NULL_RETURN(tabBar, "");
136 auto tabBarItem = tabBar->GetChildAtIndex(index);
137 CHECK_NULL_RETURN(tabBarItem, "");
138 auto node = AceType::DynamicCast<FrameNode>(tabBarItem);
139 CHECK_NULL_RETURN(node, "");
140 return node->GetAccessibilityProperty<NG::AccessibilityProperty>()->GetAccessibilityText(true);
141 }
142
SetOnTabBarClickEvent(std::function<void (const BaseEventInfo *)> && event)143 void TabsPattern::SetOnTabBarClickEvent(std::function<void(const BaseEventInfo*)>&& event)
144 {
145 ChangeEvent tabBarClickEvent([jsEvent = std::move(event)](int32_t index) {
146 /* js callback */
147 if (jsEvent) {
148 TabContentChangeEvent eventInfo(index);
149 jsEvent(&eventInfo);
150 }
151 });
152
153 if (onTabBarClickEvent_) {
154 (*onTabBarClickEvent_).swap(tabBarClickEvent);
155 } else {
156 onTabBarClickEvent_ = std::make_shared<ChangeEvent>(tabBarClickEvent);
157 }
158 }
159
SetAnimationStartEvent(AnimationStartEvent && event)160 void TabsPattern::SetAnimationStartEvent(AnimationStartEvent&& event)
161 {
162 if (animationStartEvent_) {
163 (*animationStartEvent_).swap(event);
164 } else {
165 auto host = GetHost();
166 CHECK_NULL_VOID(host);
167 auto tabsNode = AceType::DynamicCast<TabsNode>(host);
168 CHECK_NULL_VOID(tabsNode);
169 auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
170 CHECK_NULL_VOID(swiperNode);
171 auto eventHub = swiperNode->GetEventHub<SwiperEventHub>();
172 CHECK_NULL_VOID(eventHub);
173 animationStartEvent_ = std::make_shared<AnimationStartEvent>(std::move(event));
174 eventHub->AddAnimationStartEvent(animationStartEvent_);
175 }
176 }
177
SetAnimationEndEvent(AnimationEndEvent && event)178 void TabsPattern::SetAnimationEndEvent(AnimationEndEvent&& event)
179 {
180 if (animationEndEvent_) {
181 (*animationEndEvent_).swap(event);
182 } else {
183 auto host = GetHost();
184 CHECK_NULL_VOID(host);
185 auto tabsNode = AceType::DynamicCast<TabsNode>(host);
186 CHECK_NULL_VOID(tabsNode);
187 auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
188 CHECK_NULL_VOID(swiperNode);
189 auto eventHub = swiperNode->GetEventHub<SwiperEventHub>();
190 CHECK_NULL_VOID(eventHub);
191 animationEndEvent_ = std::make_shared<AnimationEndEvent>(std::move(event));
192 eventHub->AddAnimationEndEvent(animationEndEvent_);
193 }
194 }
195
OnUpdateShowDivider()196 void TabsPattern::OnUpdateShowDivider()
197 {
198 auto host = AceType::DynamicCast<TabsNode>(GetHost());
199 CHECK_NULL_VOID(host);
200 auto layoutProperty = host->GetLayoutProperty<TabsLayoutProperty>();
201 TabsItemDivider defaultDivider;
202 auto divider = layoutProperty->GetDivider().value_or(defaultDivider);
203 auto children = host->GetChildren();
204 if (children.size() < CHILDREN_MIN_SIZE) {
205 return;
206 }
207
208 auto dividerFrameNode = AceType::DynamicCast<FrameNode>(host->GetDivider());
209 CHECK_NULL_VOID(dividerFrameNode);
210 auto dividerRenderProperty = dividerFrameNode->GetPaintProperty<DividerRenderProperty>();
211 CHECK_NULL_VOID(dividerRenderProperty);
212 dividerRenderProperty->UpdateDividerColor(divider.color);
213
214 auto dividerLayoutProperty = dividerFrameNode->GetLayoutProperty<DividerLayoutProperty>();
215 CHECK_NULL_VOID(dividerLayoutProperty);
216 dividerLayoutProperty->UpdateStrokeWidth(divider.strokeWidth);
217 dividerFrameNode->MarkModifyDone();
218 }
219
UpdateSwiperDisableSwipe(bool disableSwipe)220 void TabsPattern::UpdateSwiperDisableSwipe(bool disableSwipe)
221 {
222 auto tabsNode = AceType::DynamicCast<TabsNode>(GetHost());
223 CHECK_NULL_VOID(tabsNode);
224 auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
225 CHECK_NULL_VOID(swiperNode);
226 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
227 CHECK_NULL_VOID(swiperPattern);
228 auto props = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
229 CHECK_NULL_VOID(props);
230 props->UpdateDisableSwipe(disableSwipe);
231 swiperPattern->UpdateSwiperPanEvent(disableSwipe);
232 swiperPattern->SetSwiperEventCallback(disableSwipe);
233 }
234
SetSwiperPaddingAndBorder()235 void TabsPattern::SetSwiperPaddingAndBorder()
236 {
237 auto tabsNode = AceType::DynamicCast<TabsNode>(GetHost());
238 CHECK_NULL_VOID(tabsNode);
239 auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
240 CHECK_NULL_VOID(swiperNode);
241 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
242 CHECK_NULL_VOID(swiperPattern);
243 auto layoutProperty = tabsNode->GetLayoutProperty<TabsLayoutProperty>();
244 CHECK_NULL_VOID(layoutProperty);
245 swiperPattern->SetTabsPaddingAndBorder(layoutProperty->CreatePaddingAndBorder());
246 }
247
OnModifyDone()248 void TabsPattern::OnModifyDone()
249 {
250 Pattern::OnModifyDone();
251 auto tabsNode = AceType::DynamicCast<TabsNode>(GetHost());
252 CHECK_NULL_VOID(tabsNode);
253 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
254 CHECK_NULL_VOID(tabBarNode);
255 auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>();
256 CHECK_NULL_VOID(tabBarPattern);
257 auto tabBarPaintProperty = tabBarPattern->GetPaintProperty<TabBarPaintProperty>();
258 if (tabBarPaintProperty->GetTabBarBlurStyle().has_value() &&
259 Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
260 auto tabBarRenderContext = tabBarNode->GetRenderContext();
261 CHECK_NULL_VOID(tabBarRenderContext);
262 BlurStyleOption styleOption;
263 styleOption.blurStyle = tabBarPaintProperty->GetTabBarBlurStyle().value();
264 tabBarRenderContext->UpdateBackBlurStyle(styleOption);
265 }
266
267 UpdateSwiperDisableSwipe(isCustomAnimation_ ? true : isDisableSwipe_);
268 SetSwiperPaddingAndBorder();
269
270 if (onChangeEvent_) {
271 return;
272 }
273 SetOnChangeEvent(nullptr);
274 OnUpdateShowDivider();
275 }
276
OnAfterModifyDone()277 void TabsPattern::OnAfterModifyDone()
278 {
279 auto host = GetHost();
280 CHECK_NULL_VOID(host);
281 auto inspectorId = host->GetInspectorId().value_or("");
282 if (inspectorId.empty()) {
283 return;
284 }
285 auto property = GetLayoutProperty<TabsLayoutProperty>();
286 CHECK_NULL_VOID(property);
287 auto index = property->GetIndexValue(0);
288 auto tabBarText = GetTabBarTextByIndex(index);
289 Recorder::NodeDataCache::Get().PutMultiple(inspectorId, tabBarText, index);
290 }
291
SetOnIndexChangeEvent(std::function<void (const BaseEventInfo *)> && event)292 void TabsPattern::SetOnIndexChangeEvent(std::function<void(const BaseEventInfo*)>&& event)
293 {
294 auto tabsNode = AceType::DynamicCast<TabsNode>(GetHost());
295 CHECK_NULL_VOID(tabsNode);
296 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
297 CHECK_NULL_VOID(tabBarNode);
298 auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>();
299 CHECK_NULL_VOID(tabBarPattern);
300 auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
301 CHECK_NULL_VOID(swiperNode);
302
303 ChangeEvent changeEvent([tabBarPattern, jsEvent = std::move(event)](int32_t index) {
304 if (tabBarPattern->IsMaskAnimationExecuted()) {
305 return;
306 }
307
308 /* js callback */
309 if (jsEvent) {
310 TabContentChangeEvent eventInfo(index);
311 jsEvent(&eventInfo);
312 }
313 });
314
315 if (onIndexChangeEvent_) {
316 (*onIndexChangeEvent_).swap(changeEvent);
317 } else {
318 onIndexChangeEvent_ = std::make_shared<ChangeEvent>(changeEvent);
319 auto eventHub = swiperNode->GetEventHub<SwiperEventHub>();
320 CHECK_NULL_VOID(eventHub);
321 eventHub->AddOnChangeEvent(onIndexChangeEvent_);
322 }
323 }
324
ProvideRestoreInfo()325 std::string TabsPattern::ProvideRestoreInfo()
326 {
327 auto jsonObj = JsonUtil::Create(true);
328 auto tabsNode = AceType::DynamicCast<TabsNode>(GetHost());
329 CHECK_NULL_RETURN(tabsNode, "");
330 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
331 CHECK_NULL_RETURN(tabBarNode, "");
332 auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>();
333 CHECK_NULL_RETURN(tabBarPattern, "");
334 return tabBarPattern->ProvideRestoreInfo();
335 }
336
OnRestoreInfo(const std::string & restoreInfo)337 void TabsPattern::OnRestoreInfo(const std::string& restoreInfo)
338 {
339 auto tabsNode = AceType::DynamicCast<TabsNode>(GetHost());
340 CHECK_NULL_VOID(tabsNode);
341 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
342 CHECK_NULL_VOID(tabBarNode);
343 auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>();
344 CHECK_NULL_VOID(tabBarPattern);
345 auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
346 CHECK_NULL_VOID(swiperNode);
347 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
348 CHECK_NULL_VOID(swiperPattern);
349 auto swiperLayoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
350 CHECK_NULL_VOID(swiperLayoutProperty);
351 auto info = JsonUtil::ParseJsonString(restoreInfo);
352 if (!info->IsValid() || !info->IsObject()) {
353 return;
354 }
355 auto jsonIsOn = info->GetValue("Index");
356 swiperLayoutProperty->UpdateIndex(jsonIsOn->GetInt());
357
358 swiperPattern->OnRestoreInfo(restoreInfo);
359 tabBarPattern->OnRestoreInfo(restoreInfo);
360 }
361
GetScopeFocusAlgorithm()362 ScopeFocusAlgorithm TabsPattern::GetScopeFocusAlgorithm()
363 {
364 auto property = GetLayoutProperty<TabsLayoutProperty>();
365 CHECK_NULL_RETURN(property, {});
366 bool isVertical = true;
367 if (property->GetAxis().has_value()) {
368 isVertical = property->GetAxis().value() == Axis::HORIZONTAL;
369 }
370 return ScopeFocusAlgorithm(isVertical, true, ScopeType::OTHERS,
371 [wp = WeakClaim(this)](
372 FocusStep step, const WeakPtr<FocusHub>& currFocusNode, WeakPtr<FocusHub>& nextFocusNode) {
373 auto tabs = wp.Upgrade();
374 if (tabs) {
375 nextFocusNode = tabs->GetNextFocusNode(step, currFocusNode);
376 }
377 });
378 }
379
GetNextFocusNode(FocusStep step,const WeakPtr<FocusHub> & currentFocusNode)380 WeakPtr<FocusHub> TabsPattern::GetNextFocusNode(FocusStep step, const WeakPtr<FocusHub>& currentFocusNode)
381 {
382 auto curFocusNode = currentFocusNode.Upgrade();
383 CHECK_NULL_RETURN(curFocusNode, nullptr);
384
385 auto property = GetLayoutProperty<TabsLayoutProperty>();
386 CHECK_NULL_RETURN(property, nullptr);
387 auto axis = property->GetAxis().value_or(Axis::HORIZONTAL);
388 auto tabBarPosition = property->GetTabBarPosition().value_or(BarPosition::START);
389
390 auto tabsNode = AceType::DynamicCast<TabsNode>(GetHost());
391 CHECK_NULL_RETURN(tabsNode, nullptr);
392 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
393 CHECK_NULL_RETURN(tabBarNode, nullptr);
394 auto tabBarFocusNode = tabBarNode->GetFocusHub();
395 CHECK_NULL_RETURN(tabBarFocusNode, nullptr);
396 auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
397 CHECK_NULL_RETURN(swiperNode, nullptr);
398 auto swiperFocusNode = swiperNode->GetFocusHub();
399 CHECK_NULL_RETURN(swiperFocusNode, nullptr);
400
401 auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>();
402 CHECK_NULL_RETURN(tabBarPattern, nullptr);
403 tabBarPattern->SetFirstFocus(true);
404
405 if (curFocusNode->GetFrameName() == V2::TAB_BAR_ETS_TAG &&
406 ((tabBarPosition == BarPosition::START && axis == Axis::HORIZONTAL && step == FocusStep::DOWN) ||
407 (tabBarPosition == BarPosition::START && axis == Axis::VERTICAL && step == FocusStep::RIGHT) ||
408 (tabBarPosition == BarPosition::END && axis == Axis::HORIZONTAL && step == FocusStep::UP) ||
409 (tabBarPosition == BarPosition::END && axis == Axis::VERTICAL && step == FocusStep::LEFT))) {
410 return AceType::WeakClaim(AceType::RawPtr(swiperFocusNode));
411 }
412 if (curFocusNode->GetFrameName() == V2::SWIPER_ETS_TAG) {
413 if ((tabBarPosition == BarPosition::START && axis == Axis::HORIZONTAL && step == FocusStep::UP) ||
414 (tabBarPosition == BarPosition::START && axis == Axis::VERTICAL && step == FocusStep::LEFT) ||
415 (tabBarPosition == BarPosition::END && axis == Axis::HORIZONTAL && step == FocusStep::DOWN) ||
416 (tabBarPosition == BarPosition::END && axis == Axis::VERTICAL && step == FocusStep::RIGHT)) {
417 return AceType::WeakClaim(AceType::RawPtr(tabBarFocusNode));
418 }
419 if (step == FocusStep::LEFT_END || step == FocusStep::RIGHT_END || step == FocusStep::UP_END ||
420 step == FocusStep::DOWN_END) {
421 return AceType::WeakClaim(AceType::RawPtr(swiperFocusNode));
422 }
423 }
424 return nullptr;
425 }
426
BeforeCreateLayoutWrapper()427 void TabsPattern::BeforeCreateLayoutWrapper()
428 {
429 auto tabsNode = AceType::DynamicCast<TabsNode>(GetHost());
430 CHECK_NULL_VOID(tabsNode);
431 auto swiperNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabs());
432 CHECK_NULL_VOID(swiperNode);
433 auto tabContentNum = swiperNode->TotalChildCount();
434 auto tabsLayoutProperty = GetLayoutProperty<TabsLayoutProperty>();
435 CHECK_NULL_VOID(tabsLayoutProperty);
436 auto index = tabsLayoutProperty->GetIndex().value_or(0);
437 if (index > tabContentNum - 1) {
438 index = 0;
439 }
440
441 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabsNode->GetTabBar());
442 CHECK_NULL_VOID(tabBarNode);
443 auto tabBarPattern = tabBarNode->GetPattern<TabBarPattern>();
444 CHECK_NULL_VOID(tabBarPattern);
445 if (!tabBarPattern->IsMaskAnimationByCreate()) {
446 return;
447 }
448 auto tabBarLayoutProperty = tabBarNode->GetLayoutProperty<TabBarLayoutProperty>();
449 CHECK_NULL_VOID(tabBarLayoutProperty);
450 tabBarLayoutProperty->UpdateIndicator(index);
451 tabBarPattern->UpdateTextColorAndFontWeight(index);
452 tabBarPattern->UpdateImageColor(index);
453 auto swiperLayoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
454 CHECK_NULL_VOID(swiperLayoutProperty);
455 swiperLayoutProperty->UpdateIndex(index);
456 tabsLayoutProperty->UpdateIndex(index);
457 }
458 } // namespace OHOS::Ace::NG
459