enable lazy load for tabs and fix the problem of tab content.

Signed-off-by: yan-shuifeng <yanshuifeng@huawei.com>
Change-Id: I8d6edab56e22ddb9a025acab62c35d9366a3bd05
This commit is contained in:
yan-shuifeng
2022-03-11 15:35:40 +08:00
parent 9d3414329c
commit 9e5d1d8be5
37 changed files with 561 additions and 219 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -24,7 +24,7 @@
#include "base/utils/system_properties.h"
#ifdef ACE_INSTANCE_LOG
#define ACE_FMT_PREFIX "[%{private}s(%{private}s)-(%{public}d)] "
#define ACE_FMT_PREFIX "[%{public}s(%{public}s)-(%{public}d)] "
#define ACE_LOG_ID , OHOS::Ace::LogWrapper::GetId()
#else
#define ACE_FMT_PREFIX "[%{private}s(%{private}s)] "
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -133,7 +133,7 @@ void DOMTabBar::OnMounted(const RefPtr<DOMNode>& parentNode)
lastIndex_ = parentNodeTmp->GetTabIndex();
controllerId_ = parentNodeTmp->GetTabControllerId();
const auto& controller = parentNodeTmp->GetTabController();
controller->SetIndex(lastIndex_);
controller->SetIndexWithoutChangeContent(static_cast<int32_t>(lastIndex_));
tabBarChild_->SetController(controller);
PrepareChangeListener();
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -93,7 +93,7 @@ void DOMTabContent::OnMounted(const RefPtr<DOMNode>& parentNode)
index_ = parentNodeTmp->GetTabIndex();
controllerId_ = parentNodeTmp->GetTabControllerId();
const auto& controller = parentNodeTmp->GetTabController();
controller->SetIndex(index_);
controller->SetIndexWithoutChangeContent(static_cast<int32_t>(index_));
tabContentChild_->SetController(controller);
vertical_ = parentNodeTmp->IsVertical();
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -32,15 +32,19 @@ constexpr char DEFAULT_TAB_BAR_NAME[] = "TabBar";
void JSTabContent::Create()
{
auto tabsComponent = AceType::DynamicCast<TabsComponent>(ViewStackProcessor::GetInstance()->GetTopTabs());
auto tabsComponent = AceType::DynamicCast<V2::TabsComponent>(ViewStackProcessor::GetInstance()->GetTopTabs());
if (tabsComponent) {
auto tabBar = tabsComponent->GetTabBarChild();
std::list<RefPtr<Component>> components;
auto tabContentItemComponent = AceType::MakeRefPtr<TabContentItemComponent>(components);
auto tabContentItemComponent = AceType::MakeRefPtr<V2::TabContentItemComponent>(components);
tabContentItemComponent->SetCrossAxisSize(CrossAxisSize::MAX);
tabContentItemComponent->SetTabsComponent(AceType::WeakClaim(AceType::RawPtr(tabsComponent)));
tabBar->AppendChild(CreateTabBarLabelComponent(tabContentItemComponent, std::string(DEFAULT_TAB_BAR_NAME)));
ViewStackProcessor::GetInstance()->Push(tabContentItemComponent);
auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
if (box) {
box->SetBoxClipFlag(true);
}
} else {
LOGE("fail to create tab content due to tabs missing");
}
@@ -49,12 +53,12 @@ void JSTabContent::Create()
void JSTabContent::SetTabBar(const JSCallbackInfo& info)
{
auto tabContentItemComponent =
AceType::DynamicCast<TabContentItemComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
AceType::DynamicCast<V2::TabContentItemComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
if (!tabContentItemComponent) {
return;
}
auto weakTabs = tabContentItemComponent->GetTabsComponent();
RefPtr<TabsComponent> tabs = weakTabs.Upgrade();
auto tabs = weakTabs.Upgrade();
if (!tabs) {
LOGE("can not get Tabs parent component error.");
return;
@@ -97,7 +101,7 @@ void JSTabContent::SetTabBar(const JSCallbackInfo& info)
}
RefPtr<Component> JSTabContent::ProcessTabBarBuilderFunction(
RefPtr<TabContentItemComponent>& tabContent, const JSRef<JSObject> builderFunc)
RefPtr<V2::TabContentItemComponent>& tabContent, JSRef<JSObject> builderFunc)
{
tabContent->SetBarText("custom");
ScopedViewStackProcessor builderViewStackProcessor;
@@ -109,7 +113,7 @@ RefPtr<Component> JSTabContent::ProcessTabBarBuilderFunction(
}
RefPtr<TextComponent> JSTabContent::CreateTabBarLabelComponent(
RefPtr<TabContentItemComponent>& tabContent, const std::string& labelStr)
RefPtr<V2::TabContentItemComponent>& tabContent, const std::string& labelStr)
{
tabContent->SetBarText(labelStr);
auto text = AceType::MakeRefPtr<TextComponent>(labelStr);
@@ -123,7 +127,7 @@ RefPtr<TextComponent> JSTabContent::CreateTabBarLabelComponent(
}
RefPtr<TextComponent> JSTabContent::ProcessTabBarLabel(
RefPtr<TabContentItemComponent>& tabContent, JSRef<JSVal> labelVal)
RefPtr<V2::TabContentItemComponent>& tabContent, JSRef<JSVal> labelVal)
{
std::string textStr;
if (!ParseJsString(labelVal, textStr)) {
@@ -133,7 +137,7 @@ RefPtr<TextComponent> JSTabContent::ProcessTabBarLabel(
}
RefPtr<Component> JSTabContent::ProcessTabBarTextIconPair(
RefPtr<TabContentItemComponent>& tabContent, JSRef<JSVal> textVal, JSRef<JSVal> iconVal)
RefPtr<V2::TabContentItemComponent>& tabContent, JSRef<JSVal> textVal, JSRef<JSVal> iconVal)
{
std::string iconUri;
if (!ParseJsMedia(iconVal, iconUri)) {
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -19,8 +19,8 @@
#include "frameworks/bridge/declarative_frontend/engine/functions/js_function.h"
#include "frameworks/bridge/declarative_frontend/jsview/js_container_base.h"
#include "frameworks/core/components/tab_bar/tab_content_component.h"
#include "frameworks/core/components/tab_bar/tab_content_item_component.h"
#include "frameworks/core/components/tab_bar/tabs_component.h"
#include "frameworks/core/components_v2/tabs/tab_content_item_component.h"
#include "frameworks/core/components_v2/tabs/tabs_component.h"
namespace OHOS::Ace::Framework {
@@ -50,12 +50,13 @@ protected:
private:
static RefPtr<Component> ProcessTabBarBuilderFunction(
RefPtr<TabContentItemComponent>& tabContent, JSRef<JSObject> builderFunc);
RefPtr<V2::TabContentItemComponent>& tabContent, JSRef<JSObject> builderFunc);
static RefPtr<Component> ProcessTabBarTextIconPair(
RefPtr<TabContentItemComponent>& tabContent, JSRef<JSVal> text, JSRef<JSVal> icon);
RefPtr<V2::TabContentItemComponent>& tabContent, JSRef<JSVal> text, JSRef<JSVal> icon);
static RefPtr<TextComponent> CreateTabBarLabelComponent(
RefPtr<TabContentItemComponent>& tabContent, const std::string& labelStr);
static RefPtr<TextComponent> ProcessTabBarLabel(RefPtr<TabContentItemComponent>& tabContent, JSRef<JSVal> labelVal);
RefPtr<V2::TabContentItemComponent>& tabContent, const std::string& labelStr);
static RefPtr<TextComponent> ProcessTabBarLabel(
RefPtr<V2::TabContentItemComponent>& tabContent, JSRef<JSVal> labelVal);
};
} // namespace OHOS::Ace::Framework
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -17,7 +17,7 @@
#include "core/components/tab_bar/tab_bar_component.h"
#include "core/components/tab_bar/tab_content_component.h"
#include "core/components/tab_bar/tabs_component.h"
#include "core/components_v2/tabs/tabs_component.h"
#include "frameworks/bridge/declarative_frontend/jsview/js_tabs_controller.h"
#include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
@@ -50,7 +50,7 @@ void JSTabs::SetOnChange(const JSCallbackInfo& args)
ACE_SCORING_EVENT("Tabs.onChange");
func->Execute(*TabsInfo);
});
auto component = AceType::DynamicCast<TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
auto component = AceType::DynamicCast<V2::TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
if (component) {
auto tabContent = component->GetTabContentChild();
if (tabContent) {
@@ -86,12 +86,11 @@ void JSTabs::Create(const JSCallbackInfo& info)
if (!tabController) {
tabController = JSTabsController::CreateController();
}
tabController->SetIndex(index->ToNumber<int32_t>());
tabController->SetInitialIndex(index->ToNumber<int32_t>());
}
}
std::list<RefPtr<Component>> children;
RefPtr<TabsComponent> tabsComponent =
AceType::MakeRefPtr<OHOS::Ace::TabsComponent>(children, barVal, tabController);
auto tabsComponent = AceType::MakeRefPtr<V2::TabsComponent>(children, barVal, tabController);
auto tabBar = tabsComponent->GetTabBarChild();
if (tabBar) {
auto theme = GetTheme<TabTheme>();
@@ -113,7 +112,7 @@ void JSTabs::Pop()
void JSTabs::SetVertical(const std::string& value)
{
auto tabsComponent = AceType::DynamicCast<TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
auto tabsComponent = AceType::DynamicCast<V2::TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
if (!tabsComponent) {
return;
}
@@ -135,7 +134,7 @@ void JSTabs::SetVertical(const std::string& value)
void JSTabs::SetScrollable(const std::string& value)
{
auto component = AceType::DynamicCast<TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
auto component = AceType::DynamicCast<V2::TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
if (!component) {
return;
}
@@ -147,7 +146,7 @@ void JSTabs::SetScrollable(const std::string& value)
void JSTabs::SetBarMode(const std::string& value)
{
auto component = AceType::DynamicCast<TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
auto component = AceType::DynamicCast<V2::TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
if (!component) {
return;
}
@@ -159,7 +158,7 @@ void JSTabs::SetBarMode(const std::string& value)
void JSTabs::SetBarWidth(const JSCallbackInfo& info)
{
auto component = AceType::DynamicCast<TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
auto component = AceType::DynamicCast<V2::TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
if (!component) {
return;
}
@@ -187,7 +186,7 @@ void JSTabs::SetBarWidth(const JSCallbackInfo& info)
void JSTabs::SetBarHeight(const JSCallbackInfo& info)
{
auto component = AceType::DynamicCast<TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
auto component = AceType::DynamicCast<V2::TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
if (!component) {
return;
}
@@ -213,9 +212,24 @@ void JSTabs::SetBarHeight(const JSCallbackInfo& info)
}
}
void JSTabs::SetIndex(int32_t index)
{
auto component = AceType::DynamicCast<V2::TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
if (!component) {
LOGE("can not find tabs component");
return;
}
auto controller = component->GetTabsController();
if (controller) {
controller->SetPendingIndex(index);
} else {
LOGE("can not find controller");
}
}
void JSTabs::SetAnimationDuration(float value)
{
auto component = AceType::DynamicCast<TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
auto component = AceType::DynamicCast<V2::TabsComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
if (!component) {
return;
}
@@ -236,6 +250,7 @@ void JSTabs::JSBind(BindingTarget globalObj)
JSClass<JSTabs>::StaticMethod("barMode", &JSTabs::SetBarMode);
JSClass<JSTabs>::StaticMethod("barWidth", &JSTabs::SetBarWidth);
JSClass<JSTabs>::StaticMethod("barHeight", &JSTabs::SetBarHeight);
JSClass<JSTabs>::StaticMethod("index", &JSTabs::SetIndex);
JSClass<JSTabs>::StaticMethod("animationDuration", &JSTabs::SetAnimationDuration);
JSClass<JSTabs>::StaticMethod("onChange", &JSTabs::SetOnChange);
JSClass<JSTabs>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -27,6 +27,7 @@ public:
static void Pop();
protected:
static void SetIndex(int32_t number);
static void SetVertical(const std::string& value);
static void SetScrollable(const std::string& value);
static void SetBarMode(const std::string& value);
+2 -1
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Copyright (c) 2021-2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
@@ -325,6 +325,7 @@ template("ace_core_source_set") {
"$ace_root/frameworks/core/components_v2/list:ace_core_components_list_v2_$platform",
"$ace_root/frameworks/core/components_v2/pattern_lock:ace_core_components_pattern_lock_$platform",
"$ace_root/frameworks/core/components_v2/swiper:ace_core_components_swiper_v2_$platform",
"$ace_root/frameworks/core/components_v2/tabs:ace_core_components_tabs_v2_$platform",
]
if (defined(config.enable_rosen_backend) && config.enable_rosen_backend) {
+1 -4
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Copyright (c) 2021-2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
@@ -31,10 +31,7 @@ build_component("tab_bar") {
"tab_bar_size_animation.cpp",
"tab_content_component.cpp",
"tab_content_element.cpp",
"tab_content_item_component.cpp",
"tab_content_item_element.cpp",
"tab_controller.cpp",
"tabs_component.cpp",
]
rosen_sources = [
"rosen_render_tab_bar.cpp",
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -43,10 +43,7 @@ void RenderTabBar::Update(const RefPtr<Component>& component)
}
tabsSize_ = static_cast<int32_t>(tabBar->GetChildren().size());
auto tabController = tabBar->GetController();
if (tabController) {
auto index = tabController->GetIndex();
index_ = (index >= 0 && index < tabsSize_) ? index : 0;
}
FlushIndex(tabController);
if (initialUpdate_) {
auto barIndicator = tabBar->GetIndicator();
if (barIndicator) {
@@ -76,6 +73,27 @@ void RenderTabBar::Update(const RefPtr<Component>& component)
MarkNeedLayout();
}
void RenderTabBar::FlushIndex(const RefPtr<TabController>& controller)
{
if (!controller) {
return;
}
int32_t index = 0;
if (controller->IsIndexDefined()) {
index = controller->GetIndex();
} else {
auto initialIndex = controller->GetInitialIndex();
auto pendingIndex = controller->GetPendingIndex();
if (initialUpdate_ && pendingIndex < 0) {
index = initialIndex < 0 ? 0 : initialIndex;
} else {
index = pendingIndex < 0 ? 0 : pendingIndex;
}
}
index_ = index < tabsSize_ ? index : tabsSize_ - 1;
controller->SetIndexWithoutChangeContent(index_);
}
void RenderTabBar::PerformLayout()
{
tabsSize_ = 0;
@@ -96,8 +114,9 @@ void RenderTabBar::PerformLayout()
index_ = std::clamp(index_, 0, std::max(0, tabsSize_ - 1));
if (!IsRightToLeft()) {
if (tabBarWidth_ > 0 && !NearEqual(tabBarWidth_, GetLayoutParam().GetMaxSize().Width())) {
if (!isVertical_ && actualWidth_ > GetLayoutSize().Width() && GreatNotEqual(
GetLayoutParam().GetMaxSize().Width(), actualWidth_ - std::abs(scrollableOffset_.GetX()))) {
if (!isVertical_ && actualWidth_ > GetLayoutSize().Width() &&
GreatNotEqual(
GetLayoutParam().GetMaxSize().Width(), actualWidth_ - std::abs(scrollableOffset_.GetX()))) {
scrollableOffset_.SetX(scrollableOffset_.GetX() + GetLayoutParam().GetMaxSize().Width() - tabBarWidth_);
}
}
@@ -244,7 +263,7 @@ void RenderTabBar::SetIndex(int32_t index, bool force)
{
if (index < 0 || index >= tabsSize_) {
LOGW("illegal index = %{public}d", index);
index = 0;
return;
}
if (index_ != index || force) {
@@ -635,8 +654,8 @@ void RenderTabBar::OnPaintFinish()
double offsetForFocus = NormalizeToPx(OFFSET_FOR_FOCUS);
Offset offset = Offset(offsetForFocus, offsetForFocus);
layoutSize -= Size(offsetForFocus * 2.0, offsetForFocus * 2.0);
context->ShowFocusAnimation(RRect::MakeRRect(Rect(offset, layoutSize),
Radius(NormalizeToPx(focusRadiusDimension_))),
context->ShowFocusAnimation(
RRect::MakeRRect(Rect(offset, layoutSize), Radius(NormalizeToPx(focusRadiusDimension_))),
focusAnimationColor_, position + offset);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -132,6 +132,8 @@ private:
}
RefPtr<RenderNode> GetChildByIndex(int32_t index) const;
void FlushIndex(const RefPtr<TabController>& controller);
RefPtr<ClickRecognizer> clickRecognizer_;
RefPtr<Scrollable> scrollable_;
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -35,15 +35,19 @@ void RenderTabContent::Update(const RefPtr<Component>& component)
LOGW("tabContent is null");
return;
}
auto tabController = tabContent->GetController();
int32_t count = static_cast<int32_t>(tabContent->GetChildren().size());
int32_t tabIndex = tabController ? tabController->GetIndex() : 0;
if (count != contentCount_ && tabIndex >= count && tabController) {
tabController->ValidateIndex(count - 1);
tabIndex = tabController->GetIndex();
controller_ = tabContent->GetController();
ACE_DCHECK(controller_);
auto context = context_.Upgrade();
if (context && !context->GetIsDeclarative()) {
contentCount_ = (controller_->GetTotalCount() > 0) ? controller_->GetTotalCount() : 0;
int32_t tabIndex = controller_ ? controller_->GetIndex() : 0;
if (tabIndex >= contentCount_) {
controller_->ValidateIndex((contentCount_ - 1 < 0) ? 0 : (contentCount_ - 1));
tabIndex = controller_->GetIndex();
}
currentIndex_ = tabIndex;
}
currentIndex_ = tabIndex;
contentCount_ = count;
if (scrollable_ != tabContent->IsScrollable()) {
if (animator_ && animator_->IsRunning()) {
animator_->Finish();
@@ -53,7 +57,6 @@ void RenderTabContent::Update(const RefPtr<Component>& component)
scrollDuration_ = tabContent->GetScrollDuration();
isVertical_ = tabContent->IsVertical();
SetTextDirection(tabContent->GetTextDirection());
auto context = context_.Upgrade();
if (context && context->GetIsDeclarative()) {
onChangeEvent_ = AceAsyncEvent<void(const std::shared_ptr<BaseEventInfo>&)>::Create(
tabContent->GetChangeEventId(), context_);
@@ -66,6 +69,31 @@ void RenderTabContent::Update(const RefPtr<Component>& component)
Initialize(GetContext());
}
void RenderTabContent::FlushIndex()
{
contentCount_ = controller_->GetTotalCount() > 0 ? controller_->GetTotalCount() : 0;
if (contentCount_ <= 0) {
currentIndex_ = 0;
return;
}
do {
if (controller_->IsIndexDefined()) {
currentIndex_ = controller_->GetIndex();
break;
}
auto initialIndex = controller_->GetInitialIndex();
auto pendingIndex = controller_->GetPendingIndex();
if (useInitialIndex_ && pendingIndex < 0) {
currentIndex_ = initialIndex < 0 ? 0 : initialIndex;
break;
}
currentIndex_ = pendingIndex < 0 ? 0 : pendingIndex;
} while (false);
currentIndex_ = currentIndex_ < contentCount_ ? currentIndex_ : (contentCount_ - 1);
controller_->SetIndexWithoutChangeContent(currentIndex_);
useInitialIndex_ = false;
}
void RenderTabContent::Initialize(const WeakPtr<PipelineContext>& context)
{
if (!animator_) {
@@ -117,8 +145,7 @@ void RenderTabContent::FireContentChangeEvent() const
}
if (changeEvent_) {
LOGI("FireChangeEvent, index = %{public}d.", currentIndex_);
std::string param =
std::string(R"("change",{"index":)").append(std::to_string(currentIndex_).append("},null"));
std::string param = std::string(R"("change",{"index":)").append(std::to_string(currentIndex_).append("},null"));
changeEvent_(param);
}
}
@@ -237,7 +264,7 @@ void RenderTabContent::ScrollContents(int32_t newIndex, bool isLinkBar, bool fro
tabContent->HandleStartListener(newIndex, needChange, isLinkBar);
}
});
animator_->SetDuration(scrollDuration_);
animator_->SetDuration(static_cast<int32_t>(scrollDuration_));
animator_->AddInterpolator(translate_);
animator_->Play();
MarkNeedRender();
@@ -355,7 +382,7 @@ void RenderTabContent::UpdateChildPosition(double offset, int32_t currentIndex,
LOGD("UpdateChildPosition start offset = %{public}lf, from = %{public}d, to = %{public}d", offset, currentIndex,
newIndex);
if (currentIndex < 0 || currentIndex >= contentCount_) {
LOGE("currentIndex out of range, currentIndex is %{public}d", currentIndex);
LOGE("currentIndex out of range, currentIndex is %{public}d, %{public}d", currentIndex, contentCount_);
return;
}
const auto& fromItem = contentMap_[currentIndex];
@@ -438,7 +465,7 @@ void RenderTabContent::PerformLayout()
}
int32_t index = item.first;
// make sure the new requested tab start with right position, when in animation
if ((!isDragging_ && !isInAnimation_) || (index == requestedIndex_)) {
if ((!isDragging_ && !isInAnimation_) || (index == requestedIndex_) || forceUpdate_) {
if (index < currentIndex_) {
childItem->SetPosition(prevPosition);
childItem->SetHidden(true);
@@ -451,6 +478,7 @@ void RenderTabContent::PerformLayout()
}
}
}
forceUpdate_ = false;
requestedIndex_ = -1;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -58,15 +58,50 @@ public:
void AddChildContent(int32_t index, const RefPtr<RenderNode>& child)
{
LOGI("AddChildContent: %{public}d", index);
auto iter = contentMap_.begin();
while (iter != contentMap_.end()) {
if (iter->second == child) {
if (iter->first != index) {
// index has changed, clear map.
contentMap_.clear();
}
break;
}
iter++;
}
contentMap_[index] = child;
requestedIndex_ = index;
forceUpdate_ = true;
}
void RemoveChildContent(int32_t index)
{
contentMap_.erase(index);
LOGI("RemoveChildContent: %{public}d", index);
if (contentMap_.find(index) != contentMap_.end()) {
contentMap_.clear();
forceUpdate_ = true;
}
}
void RemoveChildContent(const RefPtr<RenderNode>& child)
{
LOGI("RemoveChildContent by content");
auto iter = contentMap_.begin();
while (iter != contentMap_.end()) {
if (iter->second == child) {
iter->second->SetHidden(true);
contentMap_.clear();
forceUpdate_ = true;
break;
}
iter++;
}
}
// Used by declarative element to flush index after performBuild.
void FlushIndex();
int32_t GetCurrentIndex() const
{
return currentIndex_;
@@ -141,6 +176,7 @@ private:
bool isDragging_ = false; // whether it is dragging
bool isInitialized_ = false;
bool isVertical_ = false; // whether the tab is vertical
bool forceUpdate_ = false;
int32_t contentCount_ = 0; // the count of content
int32_t currentIndex_ = 0; // the index of current tab
@@ -156,6 +192,9 @@ private:
// callbacks when updating the index
UpdateIndexFunc callback_;
UpdateIndexFunc requireCallback_;
RefPtr<TabController> controller_;
bool useInitialIndex_ = true;
};
} // namespace OHOS::Ace
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -62,11 +62,11 @@ public:
void SetIndex(int32_t index)
{
if (controller_) {
int32_t size = static_cast<int32_t>(GetChildren().size());
auto size = static_cast<int32_t>(GetChildren().size());
if (index < 0 || index >= size) {
index = 0;
}
controller_->SetIndex(index);
controller_->SetIndexWithoutChangeContent(index);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -69,7 +69,7 @@ void TabBarElement::Update()
if (controller && (controller_ != controller)) {
// Get index from old controller before replace.
if (!controller->IsIndexDefined() && controller_) {
controller->SetIndex(controller_->GetIndex());
controller->SetIndexWithoutChangeContent(controller_->GetIndex());
}
controller_ = controller;
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -17,6 +17,7 @@
#include "core/components/tab_bar/render_tab_content.h"
#include "core/components/tab_bar/tab_content_element.h"
#include "core/components_v2/tabs/tab_content_proxy_element.h"
namespace OHOS::Ace {
@@ -29,6 +30,9 @@ TabContentComponent::TabContentComponent(
RefPtr<Element> TabContentComponent::CreateElement()
{
if (useProxy_) {
return AceType::MakeRefPtr<V2::TabContentProxyElement>(GetChildren());
}
return AceType::MakeRefPtr<TabContentElement>(GetChildren());
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -114,11 +114,17 @@ public:
return domChangeEventId_;
}
void SetUseProxy(bool useProxy)
{
useProxy_ = useProxy;
}
private:
RefPtr<TabController> controller_;
bool scrollable_ = true; // the default value is true
bool vertical_ = false; // the tab is vertical or not, default value is false
bool useProxy_ = false;
float scrollDuration_ = DEFAULT_TABCONTENT_ANIMATION_DURATION;
EventMarker changeEventId_;
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -103,13 +103,12 @@ void TabContentElement::Update()
LOGE("Get tabContent failed");
return;
}
tabContent->SetUpdateType(UpdateType::REBUILD);
contents_ = tabContent->GetChildren();
auto controller = tabContent->GetController();
if (controller && (controller_ != controller)) {
// Get index from old controller before replace.
if (!controller->IsIndexDefined() && controller_) {
controller->SetIndex(controller_->GetIndex());
controller->SetIndexWithoutChangeContent(controller_->GetIndex());
}
controller_ = controller;
}
@@ -119,8 +118,9 @@ void TabContentElement::Update()
}
controller_->SetContentElement(AceType::Claim(this));
if (controller_->GetIndex() >= static_cast<int32_t>(contents_.size())) {
controller_->SetIndex(contents_.size() - 1);
controller_->SetIndexWithoutChangeContent(static_cast<int32_t>(contents_.size()) - 1);
}
controller_->SetTotalCount(static_cast<int32_t>(contents_.size()));
newComponentBuild_ = true;
}
ComponentGroupElement::Update();
@@ -133,11 +133,6 @@ void TabContentElement::PerformBuild()
ComponentGroupElement::PerformBuild();
return;
}
auto context = context_.Upgrade();
if (context && context->GetIsDeclarative()) {
PerformBuildForDeclarative();
return;
}
RefPtr<RenderTabContent> tabContent = AceType::DynamicCast<RenderTabContent>(renderNode_);
if (!tabContent || !controller_ || !renderNode_) {
LOGW("tabContent or controller is null.");
@@ -182,56 +177,6 @@ void TabContentElement::PerformBuild()
fromController_ = false;
}
void TabContentElement::PerformBuildForDeclarative()
{
RefPtr<RenderTabContent> tabContent = AceType::DynamicCast<RenderTabContent>(renderNode_);
if (!tabContent || !controller_ || !renderNode_) {
LOGW("tabContent or controller is null.");
return;
}
if (newComponentBuild_) {
newComponentBuild_ = false;
ComponentGroupElement::PerformBuild();
int32_t index = 0;
for (const auto& element : children_) {
focusIndexMap_.emplace(index);
childMap_[index] = element;
auto renderChild = element->GetRenderNode();
if (renderChild) {
tabContent->AddChildContent(index, renderChild);
}
index++;
}
if (!childMap_.empty()) {
auto maxValue = childMap_.cbegin()->first;
for (int32_t remove = index; remove < maxValue; remove++) {
focusIndexMap_.erase(remove);
childMap_.erase(remove);
tabContent->RemoveChildContent(remove);
}
}
}
// Do index change.
if (newIndex_ >= static_cast<int32_t>(contents_.size())) {
newIndex_ = contents_.size() - 1;
}
int32_t target = newIndex_ >= 0 ? newIndex_ : controller_->GetIndex();
LOGD("change to target: %{public}d", target);
// process for new content requested by drag
if (target == newIndex_) {
tabContent->UpdateDragPosition(newIndex_);
newIndex_ = -1;
}
// process for new content requested by tab bar
if (target == newBarIndex_) {
tabContent->ChangeScroll(newBarIndex_, fromController_);
UpdateLastFocusNode();
newBarIndex_ = -1;
}
lastIndex_ = target;
fromController_ = false;
}
void TabContentElement::OnFocus()
{
// invoke callback
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -35,8 +35,8 @@ public:
void PerformBuild() override;
void Update() override;
void ChangeByContent(int32_t index);
void ChangeByBar(int32_t index, bool isFromController = false);
void PrepareContent(int32_t index);
virtual void ChangeByBar(int32_t index, bool isFromController = false);
virtual void PrepareContent(int32_t index);
void ChangeDispatch(int32_t index);
RefPtr<Element> GetTabContentChild(int32_t index) const;
@@ -44,8 +44,7 @@ public:
bool RequestNextFocus(bool vertical, bool reverse, const Rect& rect) override;
bool IsFocusable() const override;
private:
void PerformBuildForDeclarative();
protected:
RefPtr<RenderNode> CreateRenderNode() override;
void UpdateLastFocusNode();
RefPtr<FocusNode> GetCurrentFocusNode() const;
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -52,7 +52,7 @@ void TabController::SetPageReady(bool ready)
void TabController::SetIndex(int32_t index)
{
if (index_ == index || index < 0) {
LOGW("Input index is not valid.");
LOGI("SetIndex: Input index is not valid, %{public}d, %{public}d", index_, index);
return;
}
indexDefined_ = true;
@@ -66,10 +66,44 @@ void TabController::SetIndex(int32_t index)
}
}
void TabController::SetInitialIndex(int32_t index)
{
if (initialIndex_ == index || index < 0) {
LOGI("SetInitialIndex: Input index is not valid, %{public}d, %{public}d", initialIndex_, index);
return;
}
initialIndex_ = index;
}
void TabController::SetIndexWithoutChangeContent(int32_t index)
{
if (index_ == index || index < 0) {
LOGI("SetIndexWithoutChangeContent: Input index is not valid, %{public}d, %{public}d", index_, index);
return;
}
indexDefined_ = true;
index_ = index;
}
void TabController::SetPendingIndex(int32_t index)
{
if (pendingIndex_ == index || index < 0) {
LOGI("SetPendingIndex: Input index is not valid, %{public}d, %{public}d", pendingIndex_, index);
return;
}
pendingIndex_ = index;
}
void TabController::SetIndexByController(int32_t index, bool blockEvent)
{
if (index_ == index || index < 0) {
LOGW("Input index is not valid.");
LOGI("SetIndexByController: Input index is not valid, %{public}d, %{public}d", index_, index);
return;
}
if (index >= totalCount_) {
LOGI("index is large than total, %{public}d, %{public}d", index, totalCount_);
SetPendingIndex(index);
indexDefined_ = false;
return;
}
indexDefined_ = true;
@@ -108,7 +142,7 @@ void TabController::ChangeDispatch(int32_t index)
void TabController::SetIndexByScrollContent(int32_t index)
{
if (index_ == index || index < 0) {
LOGW("Input index is not valid.");
LOGI("SetIndexByScrollContent: Input index is not valid, %{public}d, %{public}d", index_, index);
return;
}
indexDefined_ = true;
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -37,9 +37,31 @@ public:
int32_t GetId() const;
int32_t GetIndex() const;
void SetTotalCount(int32_t totalCount)
{
totalCount_ = totalCount;
}
int32_t GetTotalCount() const
{
return totalCount_;
}
int32_t GetInitialIndex() const
{
return initialIndex_;
}
int32_t GetPendingIndex() const
{
return pendingIndex_;
}
void ValidateIndex(int32_t maxIndex);
void SetPageReady(bool ready);
void SetIndex(int32_t index);
void SetInitialIndex(int32_t index);
void SetPendingIndex(int32_t index);
void SetIndexWithoutChangeContent(int32_t index);
void SetIndexByController(int32_t index, bool blockEvent = true);
void SetIndexByScrollContent(int32_t index);
void SetContentElement(const RefPtr<Element>& contentElement);
@@ -61,6 +83,9 @@ public:
private:
int32_t id_ = -1;
int32_t index_ = 0;
int32_t initialIndex_ = -1;
int32_t pendingIndex_ = -1;
int32_t totalCount_ = 0;
bool pageReady_ = false;
bool indexDefined_ = false;
WeakPtr<Element> contentElement_;
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -481,7 +481,7 @@ public:
private:
class LazyForEachCache final {
public:
explicit LazyForEachCache(const RefPtr<LazyForEachComponent> component)
explicit LazyForEachCache(const RefPtr<LazyForEachComponent>& component)
: lazyForEachComponent_(component), count_(component->TotalCount())
{}
~LazyForEachCache() = default;
@@ -534,7 +534,7 @@ private:
class LinearElementProxy : public ElementProxy {
public:
explicit LinearElementProxy(const WeakPtr<ElementProxyHost>& host) : ElementProxy(host) {}
virtual ~LinearElementProxy() override = default;
~LinearElementProxy() override = default;
void UpdateIndex(size_t startIndex) override
{
@@ -708,7 +708,7 @@ public:
class MultiComposedElementProxy : public LinearElementProxy {
public:
explicit MultiComposedElementProxy(const WeakPtr<ElementProxyHost>& host) : LinearElementProxy(host) {}
virtual ~MultiComposedElementProxy() override = default;
~MultiComposedElementProxy() override = default;
void Update(const RefPtr<Component>& component, size_t startIndex) override
{
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -24,7 +24,7 @@
namespace OHOS::Ace::V2 {
class GridElement : public RenderElement, public FocusGroup, public FlushEvent, private V2::ElementProxyHost {
DECLARE_ACE_TYPE(GridElement, RenderElement, FocusGroup);
DECLARE_ACE_TYPE(GridElement, RenderElement, FocusGroup, FlushEvent);
public:
void Update() override;
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -17,8 +17,8 @@
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_V2_INSPECTOR_TAB_CONTENT_COMPOSED_ELEMENT_H
#include "core/components/tab_bar/render_tab_content.h"
#include "core/components/tab_bar/tab_content_item_element.h"
#include "core/components_v2/inspector/inspector_composed_element.h"
#include "core/components_v2/tabs/tab_content_item_element.h"
#include "core/pipeline/base/composed_element.h"
namespace OHOS::Ace::V2 {
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -20,8 +20,8 @@
#include "core/components/flex/render_flex.h"
#include "core/components/tab_bar/render_tab_bar.h"
#include "core/components/tab_bar/render_tab_content.h"
#include "core/components/tab_bar/tabs_element.h"
#include "core/components_v2/inspector/inspector_composed_element.h"
#include "core/components_v2/tabs/tabs_element.h"
#include "core/pipeline/base/composed_element.h"
namespace OHOS::Ace::V2 {
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -29,7 +29,7 @@ class ListElement : public RenderElement,
public FlushEvent,
private ListItemGenerator,
private ElementProxyHost {
DECLARE_ACE_TYPE(V2::ListElement, RenderElement, FocusGroup);
DECLARE_ACE_TYPE(V2::ListElement, RenderElement, FocusGroup, FlushEvent);
public:
ListElement();
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -22,8 +22,8 @@
namespace OHOS::Ace::V2 {
class SwiperElement : public RenderElement, public FocusGroup, private V2::ElementProxyHost, public FlushEvent {
DECLARE_ACE_TYPE(SwiperElement, RenderElement, FocusGroup);
class SwiperElement : public RenderElement, public FocusGroup, public FlushEvent, private V2::ElementProxyHost {
DECLARE_ACE_TYPE(SwiperElement, RenderElement, FocusGroup, FlushEvent);
public:
void PerformBuild() override;
@@ -0,0 +1,23 @@
# Copyright (c) 2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//foundation/ace/ace_engine/frameworks/core/components/components.gni")
build_component("tabs_v2") {
sources = [
"tab_content_item_component.cpp",
"tab_content_item_element.cpp",
"tab_content_proxy_element.cpp",
"tabs_component.cpp",
]
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -13,18 +13,19 @@
* limitations under the License.
*/
#include "core/components/tab_bar/tab_content_item_component.h"
#include "core/components_v2/tabs/tab_content_item_component.h"
#include "core/components/tab_bar/tab_content_item_element.h"
#include "core/components_v2/tabs/tab_content_item_element.h"
namespace OHOS::Ace {
namespace OHOS::Ace::V2 {
TabContentItemComponent::TabContentItemComponent(
std::list<RefPtr<Component>>& children) : ColumnComponent(FlexAlign::FLEX_START, FlexAlign::FLEX_START, children) {}
TabContentItemComponent::TabContentItemComponent(std::list<RefPtr<Component>>& children)
: ColumnComponent(FlexAlign::FLEX_START, FlexAlign::FLEX_START, children)
{}
RefPtr<Element> TabContentItemComponent::CreateElement()
{
return AceType::MakeRefPtr<TabContentItemElement>();
}
} // namespace OHOS::Ace
} // namespace OHOS::Ace::V2
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -13,14 +13,14 @@
* limitations under the License.
*/
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_TAB_BAR_TAB_CONTENT_ITEM_COMPONENT_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_TAB_BAR_TAB_CONTENT_ITEM_COMPONENT_H
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_V2_TABS_TAB_CONTENT_ITEM_COMPONENT_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_V2_TABS_TAB_CONTENT_ITEM_COMPONENT_H
#include "core/components/tab_bar/tabs_component.h"
#include "core/components_v2/tabs/tabs_component.h"
#include "core/pipeline/base/element.h"
#include "frameworks/core/components/flex/flex_component.h"
namespace OHOS::Ace {
namespace OHOS::Ace::V2 {
class ACE_EXPORT TabContentItemComponent : public ColumnComponent {
DECLARE_ACE_TYPE(TabContentItemComponent, ColumnComponent);
@@ -31,7 +31,7 @@ public:
RefPtr<Element> CreateElement() override;
WeakPtr<TabsComponent> GetTabsComponent() const
WeakPtr<V2::TabsComponent> GetTabsComponent() const
{
return tabsComponent_;
}
@@ -67,6 +67,6 @@ private:
std::string barText_;
};
} // namespace OHOS::Ace
} // namespace OHOS::Ace::V2
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_TAB_BAR_TAB_CONTENT_ITEM_COMPONENT_H
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_V2_TABS_TAB_CONTENT_ITEM_COMPONENT_H
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -13,17 +13,18 @@
* limitations under the License.
*/
#include "core/components/tab_bar/tab_content_item_element.h"
#include "core/components_v2/tabs/tab_content_item_element.h"
#include "core/components/flex/flex_element.h"
#include "core/components/tab_bar/tab_content_item_component.h"
#include "core/components_v2/tabs/tab_content_item_component.h"
namespace OHOS::Ace {
namespace OHOS::Ace::V2 {
void TabContentItemElement::Update()
{
auto component = AceType::DynamicCast<TabContentItemComponent>(component_);
if (!component) {
LOGE("TabContentItemComponent is null");
return;
}
barIcon_ = component->GetBarIcon();
@@ -31,4 +32,4 @@ void TabContentItemElement::Update()
FlexElement::Update();
}
} // namespace OHOS::Ace
} // namespace OHOS::Ace::v2
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -13,12 +13,12 @@
* limitations under the License.
*/
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_TAB_BAR_TAB_CONTENT_ITEM_ELEMENT_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_TAB_BAR_TAB_CONTENT_ITEM_ELEMENT_H
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_V2_TABS_TAB_CONTENT_ITEM_ELEMENT_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_V2_TABS_TAB_CONTENT_ITEM_ELEMENT_H
#include "core/components/tab_bar/tabs_component.h"
#include "core/components_v2/tabs/tabs_component.h"
namespace OHOS::Ace {
namespace OHOS::Ace::V2 {
class TabContentItemElement : public ColumnElement {
DECLARE_ACE_TYPE(TabContentItemElement, ColumnElement);
@@ -41,6 +41,6 @@ private:
std::string barText_;
};
} // namespace OHOS::Ace
} // namespace OHOS::Ace::V2
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_TAB_BAR_TAB_CONTENT_ITEM_ELEMENT_H
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_V2_TABS_TAB_CONTENT_ITEM_ELEMENT_H
@@ -0,0 +1,158 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "core/components_v2/tabs/tab_content_proxy_element.h"
#include "core/components/tab_bar/render_tab_content.h"
namespace OHOS::Ace::V2 {
void TabContentProxyElement::Update()
{
if (!component_) {
return;
}
RefPtr<TabContentComponent> tabContent = AceType::DynamicCast<TabContentComponent>(component_);
if (!tabContent) {
LOGE("Get tabContent failed");
return;
}
contents_ = tabContent->GetChildren();
auto controller = tabContent->GetController();
if (controller && (controller_ != controller)) {
// Get index from old controller before replace.
if (controller_) {
if (!controller->IsIndexDefined()) {
controller->SetIndexWithoutChangeContent(controller_->GetIndex());
}
controller->SetTotalCount(controller_->GetTotalCount());
}
controller_ = controller;
}
if (!controller_) {
LOGE("Get controller failed");
return;
}
controller_->SetContentElement(AceType::Claim(this));
RenderElement::Update();
}
void TabContentProxyElement::PerformBuild()
{
if (component_) {
auto tabsContentComponent = AceType::DynamicCast<TabContentComponent>(component_);
if (!tabsContentComponent) {
return;
}
ElementProxyHost::UpdateChildren(tabsContentComponent->GetChildren());
}
auto tabContent = AceType::DynamicCast<RenderTabContent>(renderNode_);
if (!tabContent || !controller_) {
LOGW("tabContent or controller is null.");
return;
}
auto totalCount = static_cast<int32_t>(TotalCount());
if (newIndex_ < 0 && newBarIndex_ < 0) {
// verify controller index first build and flush index for render.
auto maxIndex = totalCount - 1;
if (controller_->GetIndex() >= totalCount) {
controller_->SetIndexWithoutChangeContent(maxIndex < 0 ? 0 : maxIndex);
}
if (controller_->GetInitialIndex() >= totalCount) {
controller_->SetInitialIndex(maxIndex < 0 ? 0 : maxIndex);
}
if (controller_->GetPendingIndex() >= totalCount) {
controller_->SetPendingIndex(maxIndex < 0 ? 0 : maxIndex);
}
controller_->SetTotalCount(totalCount < 1 ? 0 : totalCount);
tabContent->FlushIndex();
}
int32_t target = newIndex_ >= 0 ? newIndex_ : controller_->GetIndex();
auto element = GetElementByIndex(target);
if (!element) {
LOGE("GetElementByIndex failed index=[%{public}d]", target);
return;
}
auto renderNode = element->GetRenderNode();
if (!renderNode) {
LOGE("GetRenderNode failed");
return;
}
tabContent->AddChildContent(target, renderNode);
focusIndexMap_.emplace(target);
renderNode_->MarkNeedLayout();
// process for new content requested by drag
if (target == newIndex_) {
tabContent->UpdateDragPosition(newIndex_);
newIndex_ = -1;
}
// process for new content requested by tab bar
if (target == newBarIndex_) {
tabContent->ChangeScroll(newBarIndex_, fromController_);
UpdateLastFocusNode();
newBarIndex_ = -1;
}
lastIndex_ = target;
fromController_ = false;
}
// In ChangeByBar function the controller has already set index.
void TabContentProxyElement::ChangeByBar(int32_t index, bool isFromController)
{
LOGD("change content by tab bar index: %{public}d", index);
newBarIndex_ = index;
fromController_ = isFromController;
PerformBuild();
}
void TabContentProxyElement::PrepareContent(int32_t index)
{
LOGD("request prepareContent new index: %{public}d", index);
newIndex_ = index;
PerformBuild();
}
RefPtr<Element> TabContentProxyElement::OnUpdateElement(
const RefPtr<Element>& element, const RefPtr<Component>& component)
{
if (element && !component) {
auto tabContent = AceType::DynamicCast<RenderTabContent>(renderNode_);
if (!tabContent) {
LOGE("tabContent is null.");
} else {
auto renderNode = element->GetRenderNode();
if (!renderNode) {
LOGW("delete render child is null.");
} else {
tabContent->RemoveChildContent(renderNode);
}
}
}
return UpdateChild(element, component);
}
RefPtr<Component> TabContentProxyElement::OnMakeEmptyComponent()
{
LOGI("tab content does not support lazyForEach yet");
return nullptr;
}
void TabContentProxyElement::OnDataSourceUpdated(size_t startIndex)
{
LOGI("tab content does not support lazyForEach yet");
}
} // namespace OHOS::Ace::V2
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_V2_TABS__TAB_CONTENT_PROXY_ELEMENT_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_V2_TABS__TAB_CONTENT_PROXY_ELEMENT_H
#include <list>
#include <unordered_map>
#include "core/components/tab_bar/tab_content_element.h"
#include "core/components/tab_bar/tab_controller.h"
#include "core/components_v2/common/element_proxy.h"
#include "core/focus/focus_node.h"
namespace OHOS::Ace::V2 {
class TabContentProxyElement : public TabContentElement, private ElementProxyHost {
DECLARE_ACE_TYPE(TabContentElement, TabContentElement);
public:
explicit TabContentProxyElement(const std::list<RefPtr<Component>>& contents) : TabContentElement(contents) {};
~TabContentProxyElement() override = default;
void PerformBuild() override;
void Update() override;
void ChangeByBar(int32_t index, bool isFromController = false) override;
void PrepareContent(int32_t index) override;
private:
RefPtr<Element> OnUpdateElement(const RefPtr<Element>& element, const RefPtr<Component>& component) override;
RefPtr<Component> OnMakeEmptyComponent() override;
void OnDataSourceUpdated(size_t startIndex) override;
};
} // namespace OHOS::Ace::V2
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_V2_TABS__TAB_CONTENT_PROXY_ELEMENT_H
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -13,13 +13,13 @@
* limitations under the License.
*/
#include "core/components/tab_bar/tabs_component.h"
#include "core/components_v2/tabs/tabs_component.h"
#include "core/components/clip/clip_component.h"
#include "core/components/foreach/for_each_component.h"
#include "core/components/tab_bar/tabs_element.h"
#include "core/components_v2/tabs/tabs_element.h"
namespace OHOS::Ace {
namespace OHOS::Ace::V2 {
namespace {
int32_t g_tabControllerId = 0;
@@ -40,6 +40,7 @@ TabsComponent::TabsComponent(
tabBar_ = AceType::MakeRefPtr<TabBarComponent>(tabBarChildren_, controller_, tabBarIndicator_);
tabBar_->SetBarPosition(barPosition);
tabContent_ = AceType::MakeRefPtr<TabContentComponent>(tabContentChildren_, controller_);
tabContent_->SetUseProxy(true);
flexItem_ = AceType::MakeRefPtr<FlexItemComponent>(0, 1, 0);
flexItem_->SetChild(tabContent_);
auto box = AceType::MakeRefPtr<BoxComponent>();
@@ -62,24 +63,12 @@ RefPtr<Element> TabsComponent::CreateElement()
void TabsComponent::AppendChild(const RefPtr<Component>& child)
{
if (AceType::InstanceOf<ForEachComponent>(child)) {
auto children = DynamicCast<ForEachComponent>(child)->GetChildren();
for (auto&& item : children) {
auto clip = AceType::MakeRefPtr<ClipComponent>(item);
clip->SetFollowChild(false);
tabContent_->AppendChildDirectly(clip);
}
return;
}
auto clip = AceType::MakeRefPtr<ClipComponent>(child);
clip->SetFollowChild(false);
tabContent_->AppendChildDirectly(clip);
tabContent_->AppendChildDirectly(child);
}
void TabsComponent::RemoveChild(const RefPtr<Component>& child)
{
auto clip = AceType::DynamicCast<ClipComponent>(child);
tabContent_->RemoveChildDirectly(clip);
tabContent_->RemoveChildDirectly(child);
}
} // namespace OHOS::Ace
} // namespace OHOS::Ace::V2
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -13,8 +13,8 @@
* limitations under the License.
*/
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_TAB_BAR_TABS_COMPONENT_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_TAB_BAR_TABS_COMPONENT_H
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_V2_TABS_TABS_COMPONENT_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_V2_TABS_TABS_COMPONENT_H
#include "core/components/tab_bar/tab_controller.h"
#include "core/pipeline/base/component_group.h"
@@ -22,10 +22,10 @@
#include "core/pipeline/base/render_node.h"
#include "frameworks/core/components/flex/flex_component.h"
#include "frameworks/core/components/flex/flex_item_component.h"
#include "frameworks/core/components/tab_bar/tab_content_component.h"
#include "frameworks/core/components/tab_bar/tab_bar_component.h"
#include "frameworks/core/components/tab_bar/tab_content_component.h"
namespace OHOS::Ace {
namespace OHOS::Ace::V2 {
class ACE_EXPORT TabsComponent : public FlexComponent {
DECLARE_ACE_TYPE(TabsComponent, FlexComponent);
@@ -71,6 +71,6 @@ private:
RefPtr<FlexItemComponent> flexItem_;
};
} // namespace OHOS::Ace
} // namespace OHOS::Ace::V2
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_TAB_BAR_TABS_COMPONENT_H
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_V2_TABS_TABS_COMPONENT_H
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -12,18 +12,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_TAB_BAR_TABS_ELEMENT_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_TAB_BAR_TABS_ELEMENT_H
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_V2_TABS_TABS_ELEMENT_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_V2_TABS_TABS_ELEMENT_H
#include "core/components/tab_bar/tabs_component.h"
#include "core/components_v2/tabs/tabs_component.h"
#include "core/pipeline/base/component_group_element.h"
namespace OHOS::Ace {
namespace OHOS::Ace::V2 {
class TabsElement : public ComponentGroupElement {
DECLARE_ACE_TYPE(TabsElement, ComponentGroupElement);
};
} // namespace OHOS::Ace
} // namespace OHOS::Ace::V2
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_TAB_BAR_TABS_ELEMENT_H
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_V2_TABS_TABS_ELEMENT_H